<!DOCTYPE html>
<html lang="zh-CN" dir="ltr">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>javascript高级程序设计（第4版）笔记 | Vite & Vue powered static site generator</title>
    <meta name="description" content="Nuobel 诺贝尔的源泉">
    <link rel="preload stylesheet" href="/assets/style.6550a0c8.css" as="style">
    <link rel="modulepreload" href="/assets/app.6facf8ba.js">
    <link rel="modulepreload" href="/assets/blog_readingNotes_jsgc4.md.badec6ec.lean.js">
    
    <meta name="theme-color" content="#3c8772">
  <script>var _hmt=_hmt||[];(function(){var e=document.createElement("script");e.src="https://hm.baidu.com/hm.js?b812ad2761f4f77a87ce9b80c0cae4a0";var t=document.getElementsByTagName("script")[0];t.parentNode.insertBefore(e,t)})();</script>
  <script id="check-dark-light">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
  </head>
  <body>
    <div id="app"><div class="Layout" data-v-93a960b4><!--[--><!--]--><!--[--><span tabindex="-1" data-v-151f2593></span><a href="#VPContent" class="VPSkipLink visually-hidden" data-v-151f2593> Skip to content </a><!--]--><!----><header class="VPNav" data-v-93a960b4 data-v-0fa0e57d><div class="VPNavBar has-sidebar" data-v-0fa0e57d data-v-be450ad9><div class="container" data-v-be450ad9><div class="title" data-v-be450ad9><div class="VPNavBarTitle has-sidebar" data-v-be450ad9 data-v-6d2fb2d9><a class="title" href="/" data-v-6d2fb2d9><!--[--><!--]--><!----><!--[-->Nuobel<!--]--><!--[--><!--]--></a></div></div><div class="content" data-v-be450ad9><div class="curtain" data-v-be450ad9></div><div class="content-body" data-v-be450ad9><!--[--><!--]--><!----><nav aria-labelledby="main-nav-aria-label" class="VPNavBarMenu menu" data-v-be450ad9 data-v-bdedfc22><span id="main-nav-aria-label" class="visually-hidden" data-v-bdedfc22>Main Navigation</span><!--[--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/blog/frontend/library.html" data-v-bdedfc22 data-v-95f5d58b data-v-30c06bd3><!--[-->博客<!--]--><!----></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/blog/summary/20210806.html" data-v-bdedfc22 data-v-95f5d58b data-v-30c06bd3><!--[-->日记周记<!--]--><!----></a><!--]--><!--[--><div class="VPFlyout VPNavBarMenuGroup active" data-v-bdedfc22 data-v-96001b6b><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-96001b6b><span class="text" data-v-96001b6b><!----> 读书笔记 <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="text-icon" data-v-96001b6b><path d="M12,16c-0.3,0-0.5-0.1-0.7-0.3l-6-6c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l5.3,5.3l5.3-5.3c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-6,6C12.5,15.9,12.3,16,12,16z"></path></svg></span></button><div class="menu" data-v-96001b6b><div class="VPMenu" data-v-96001b6b data-v-e7ea1737><div class="items" data-v-e7ea1737><!--[--><!--[--><div class="VPMenuGroup" data-v-e7ea1737 data-v-b66affaf><p class="title" data-v-b66affaf>前端技术</p><!--[--><!--[--><div class="VPMenuLink" data-v-b66affaf data-v-a5bbb52c><a class="VPLink link" href="/blog/svg/rumen.html" data-v-a5bbb52c data-v-30c06bd3><!--[-->SVG基础入门<!--]--><!----></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-b66affaf data-v-a5bbb52c><a class="VPLink link" href="/blog/readingNotes/browserPrinciple.html" data-v-a5bbb52c data-v-30c06bd3><!--[-->浏览器工作原理与实践<!--]--><!----></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-b66affaf data-v-a5bbb52c><a class="VPLink link" href="/blog/readingNotes/reactAndNodeJS.html" data-v-a5bbb52c data-v-30c06bd3><!--[-->react+Node.js开发实战<!--]--><!----></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-b66affaf data-v-a5bbb52c><a class="VPLink link active" href="/blog/readingNotes/jsgc4.html" data-v-a5bbb52c data-v-30c06bd3><!--[-->javascript高级程序设计第4版<!--]--><!----></a></div><!--]--><!--]--></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/blog/interviews/" data-v-bdedfc22 data-v-95f5d58b data-v-30c06bd3><!--[-->面试<!--]--><!----></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/photograph/home.html" data-v-bdedfc22 data-v-95f5d58b data-v-30c06bd3><!--[-->摄影<!--]--><!----></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/english/plan.html" data-v-bdedfc22 data-v-95f5d58b data-v-30c06bd3><!--[-->英语<!--]--><!----></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/wemedia/what.html" data-v-bdedfc22 data-v-95f5d58b data-v-30c06bd3><!--[-->自媒体<!--]--><!----></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/life/index.html" data-v-bdedfc22 data-v-95f5d58b data-v-30c06bd3><!--[-->生活<!--]--><!----></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/about/me.html" data-v-bdedfc22 data-v-95f5d58b data-v-30c06bd3><!--[-->关于 <!--]--><!----></a><!--]--><!--]--></nav><!----><div class="VPNavBarAppearance appearance" data-v-be450ad9 data-v-da3f667a><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" aria-label="toggle dark mode" aria-checked="false" data-v-da3f667a data-v-0d529b6d data-v-f3c41672><span class="check" data-v-f3c41672><span class="icon" data-v-f3c41672><!--[--><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="sun" data-v-0d529b6d><path d="M12,18c-3.3,0-6-2.7-6-6s2.7-6,6-6s6,2.7,6,6S15.3,18,12,18zM12,8c-2.2,0-4,1.8-4,4c0,2.2,1.8,4,4,4c2.2,0,4-1.8,4-4C16,9.8,14.2,8,12,8z"></path><path d="M12,4c-0.6,0-1-0.4-1-1V1c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,3.6,12.6,4,12,4z"></path><path d="M12,24c-0.6,0-1-0.4-1-1v-2c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,23.6,12.6,24,12,24z"></path><path d="M5.6,6.6c-0.3,0-0.5-0.1-0.7-0.3L3.5,4.9c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C6.2,6.5,5.9,6.6,5.6,6.6z"></path><path d="M19.8,20.8c-0.3,0-0.5-0.1-0.7-0.3l-1.4-1.4c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C20.3,20.7,20,20.8,19.8,20.8z"></path><path d="M3,13H1c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S3.6,13,3,13z"></path><path d="M23,13h-2c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S23.6,13,23,13z"></path><path d="M4.2,20.8c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C4.7,20.7,4.5,20.8,4.2,20.8z"></path><path d="M18.4,6.6c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C18.9,6.5,18.6,6.6,18.4,6.6z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="moon" data-v-0d529b6d><path d="M12.1,22c-0.3,0-0.6,0-0.9,0c-5.5-0.5-9.5-5.4-9-10.9c0.4-4.8,4.2-8.6,9-9c0.4,0,0.8,0.2,1,0.5c0.2,0.3,0.2,0.8-0.1,1.1c-2,2.7-1.4,6.4,1.3,8.4c2.1,1.6,5,1.6,7.1,0c0.3-0.2,0.7-0.3,1.1-0.1c0.3,0.2,0.5,0.6,0.5,1c-0.2,2.7-1.5,5.1-3.6,6.8C16.6,21.2,14.4,22,12.1,22zM9.3,4.4c-2.9,1-5,3.6-5.2,6.8c-0.4,4.4,2.8,8.3,7.2,8.7c2.1,0.2,4.2-0.4,5.8-1.8c1.1-0.9,1.9-2.1,2.4-3.4c-2.5,0.9-5.3,0.5-7.5-1.1C9.2,11.4,8.1,7.7,9.3,4.4z"></path></svg><!--]--></span></span></button></div><!----><div class="VPFlyout VPNavBarExtra extra" data-v-be450ad9 data-v-66bb1f24 data-v-96001b6b><button type="button" class="button" aria-haspopup="true" aria-expanded="false" aria-label="extra navigation" data-v-96001b6b><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="icon" data-v-96001b6b><circle cx="12" cy="12" r="2"></circle><circle cx="19" cy="12" r="2"></circle><circle cx="5" cy="12" r="2"></circle></svg></button><div class="menu" data-v-96001b6b><div class="VPMenu" data-v-96001b6b data-v-e7ea1737><!----><!--[--><!--[--><!----><div class="group" data-v-66bb1f24><div class="item appearance" data-v-66bb1f24><p class="label" data-v-66bb1f24>Appearance</p><div class="appearance-action" data-v-66bb1f24><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" aria-label="toggle dark mode" aria-checked="false" data-v-66bb1f24 data-v-0d529b6d data-v-f3c41672><span class="check" data-v-f3c41672><span class="icon" data-v-f3c41672><!--[--><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="sun" data-v-0d529b6d><path d="M12,18c-3.3,0-6-2.7-6-6s2.7-6,6-6s6,2.7,6,6S15.3,18,12,18zM12,8c-2.2,0-4,1.8-4,4c0,2.2,1.8,4,4,4c2.2,0,4-1.8,4-4C16,9.8,14.2,8,12,8z"></path><path d="M12,4c-0.6,0-1-0.4-1-1V1c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,3.6,12.6,4,12,4z"></path><path d="M12,24c-0.6,0-1-0.4-1-1v-2c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,23.6,12.6,24,12,24z"></path><path d="M5.6,6.6c-0.3,0-0.5-0.1-0.7-0.3L3.5,4.9c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C6.2,6.5,5.9,6.6,5.6,6.6z"></path><path d="M19.8,20.8c-0.3,0-0.5-0.1-0.7-0.3l-1.4-1.4c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C20.3,20.7,20,20.8,19.8,20.8z"></path><path d="M3,13H1c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S3.6,13,3,13z"></path><path d="M23,13h-2c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S23.6,13,23,13z"></path><path d="M4.2,20.8c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C4.7,20.7,4.5,20.8,4.2,20.8z"></path><path d="M18.4,6.6c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C18.9,6.5,18.6,6.6,18.4,6.6z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="moon" data-v-0d529b6d><path d="M12.1,22c-0.3,0-0.6,0-0.9,0c-5.5-0.5-9.5-5.4-9-10.9c0.4-4.8,4.2-8.6,9-9c0.4,0,0.8,0.2,1,0.5c0.2,0.3,0.2,0.8-0.1,1.1c-2,2.7-1.4,6.4,1.3,8.4c2.1,1.6,5,1.6,7.1,0c0.3-0.2,0.7-0.3,1.1-0.1c0.3,0.2,0.5,0.6,0.5,1c-0.2,2.7-1.5,5.1-3.6,6.8C16.6,21.2,14.4,22,12.1,22zM9.3,4.4c-2.9,1-5,3.6-5.2,6.8c-0.4,4.4,2.8,8.3,7.2,8.7c2.1,0.2,4.2-0.4,5.8-1.8c1.1-0.9,1.9-2.1,2.4-3.4c-2.5,0.9-5.3,0.5-7.5-1.1C9.2,11.4,8.1,7.7,9.3,4.4z"></path></svg><!--]--></span></span></button></div></div></div><!----><!--]--><!--]--></div></div></div><!--[--><!--]--><button type="button" class="VPNavBarHamburger hamburger" aria-label="mobile navigation" aria-expanded="false" aria-controls="VPNavScreen" data-v-be450ad9 data-v-e5dd9c1c><span class="container" data-v-e5dd9c1c><span class="top" data-v-e5dd9c1c></span><span class="middle" data-v-e5dd9c1c></span><span class="bottom" data-v-e5dd9c1c></span></span></button></div></div></div></div><!----></header><div class="VPLocalNav" data-v-93a960b4 data-v-2817d72e><button class="menu" aria-expanded="false" aria-controls="VPSidebarNav" data-v-2817d72e><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="menu-icon" data-v-2817d72e><path d="M17,11H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h14c0.6,0,1,0.4,1,1S17.6,11,17,11z"></path><path d="M21,7H3C2.4,7,2,6.6,2,6s0.4-1,1-1h18c0.6,0,1,0.4,1,1S21.6,7,21,7z"></path><path d="M21,15H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h18c0.6,0,1,0.4,1,1S21.6,15,21,15z"></path><path d="M17,19H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h14c0.6,0,1,0.4,1,1S17.6,19,17,19z"></path></svg><span class="menu-text" data-v-2817d72e>菜单</span></button><a class="top-link" href="#" data-v-2817d72e>回到顶部</a></div><aside class="VPSidebar" data-v-93a960b4 data-v-c79ccefa><div class="curtain" data-v-c79ccefa></div><nav class="nav" id="VPSidebarNav" aria-labelledby="sidebar-aria-label" tabindex="-1" data-v-c79ccefa><span class="visually-hidden" id="sidebar-aria-label" data-v-c79ccefa> Sidebar Navigation </span><!--[--><!--]--><!--[--><div class="group" data-v-c79ccefa><section class="VPSidebarItem level-0 has-active" data-v-c79ccefa data-v-b05232f3><div class="item" role="button" data-v-b05232f3><div class="indicator" data-v-b05232f3></div><a class="VPLink link" data-v-b05232f3 data-v-30c06bd3><!--[--><h2 class="text" data-v-b05232f3>javascript高级程序设计第4版</h2><!--]--><!----></a><!----></div><div class="items" data-v-b05232f3><!--[--><div class="VPSidebarItem level-1 is-link is-active has-active" data-v-b05232f3 data-v-b05232f3><div class="item" data-v-b05232f3><div class="indicator" data-v-b05232f3></div><a class="VPLink link link" href="/blog/readingNotes/jsgc4.html" data-v-b05232f3 data-v-30c06bd3><!--[--><p class="text" data-v-b05232f3>第1-13章</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b05232f3 data-v-b05232f3><div class="item" data-v-b05232f3><div class="indicator" data-v-b05232f3></div><a class="VPLink link link" href="/blog/readingNotes/jsgc4-2.html" data-v-b05232f3 data-v-30c06bd3><!--[--><p class="text" data-v-b05232f3>第14-26章</p><!--]--><!----></a><!----></div><!----></div><!--]--></div></section></div><!--]--><!--[--><!--]--></nav></aside><div class="VPContent has-sidebar" id="VPContent" data-v-93a960b4 data-v-0bd490fb><div class="VPDoc has-sidebar has-aside" data-v-0bd490fb data-v-c5936a1e><div class="container" data-v-c5936a1e><div class="aside" data-v-c5936a1e><div class="aside-curtain" data-v-c5936a1e></div><div class="aside-container" data-v-c5936a1e><div class="aside-content" data-v-c5936a1e><div class="VPDocAside" data-v-c5936a1e data-v-cdc66372><!--[--><!--]--><!--[--><!--]--><div class="VPDocAsideOutline" data-v-cdc66372 data-v-5dd9d5f6><div class="content" data-v-5dd9d5f6><div class="outline-marker" data-v-5dd9d5f6></div><div class="outline-title" data-v-5dd9d5f6>本页目录</div><nav aria-labelledby="doc-outline-aria-label" data-v-5dd9d5f6><span class="visually-hidden" id="doc-outline-aria-label" data-v-5dd9d5f6> Table of Contents for current page </span><ul class="root" data-v-5dd9d5f6 data-v-1188541a><!--[--><!--]--></ul></nav></div></div><!--[--><!--]--><div class="spacer" data-v-cdc66372></div><!--[--><!--]--><!----><!--[--><!--]--><!--[--><!--]--></div></div></div></div><div class="content" data-v-c5936a1e><div class="content-container" data-v-c5936a1e><!--[--><!--]--><main class="main" data-v-c5936a1e><div style="position:relative;" class="vp-doc _blog_readingNotes_jsgc4" data-v-c5936a1e><div><h2 id="前言" tabindex="-1">前言 <a class="header-anchor" href="#前言" aria-hidden="true">#</a></h2><p>今天（2020-08-17），图灵教育推出了优惠活动，js 高程的第四版电子书+纸书线上优惠价 99 元。</p><p>作为红宝书粉丝，自然是一出来就买啦，在 9.27 之前，只有电子书，每周更新几章，9.27 后发货纸书。</p><p>这篇文章记录看电子书的重要笔记。</p><h2 id="_2-html-中的-javascript" tabindex="-1">2.HTML 中的 Javascript <a class="header-anchor" href="#_2-html-中的-javascript" aria-hidden="true">#</a></h2><h3 id="_2-1-script-元素" tabindex="-1">2.1&lt;script&gt;元素 <a class="header-anchor" href="#_2-1-script-元素" aria-hidden="true">#</a></h3><p><code>&lt;script&gt;</code>元素重要的几个属性：</p><ul><li><p><strong>async</strong>：可选。html5 属性，表示应该立即开始下载脚本，但不能阻止其它页面动作，比如下载资源或等待其它脚本加载。</p></li><li><p><strong>defer</strong>：可选。html4 属性，表示在文档解析和显示完成后再执行脚本是没问题的。即可以立即下载，但执行可以推迟到页面解析完成后。</p></li><li><p><strong>integrity</strong>：可选。允许比对接收到的资源和指定的加密签名以验证子资源完整性（SRI，Subresource Intergrity）。如果接收到的资源的签名与这个属性指定的签名不匹配，则页面会报错，脚本不会执行。这个属性可以用于确保内容分发网络（CDN，Content Delivery Network）不会提供恶意内容</p></li><li><p>看下面图示 <img src="/assets/script.64034f41.png" alt=""></p></li></ul><p>不管是内嵌还是 src 引入的代码，浏览器都会按照<code>&lt;script&gt;</code>在页面中出现的顺序依次解释它们，前提是它们没有使用<code>defer</code>和<code>async</code>属性(加了<code>defer和async</code>属性的<code>&lt;script</code>元素在实际表现中执行顺序是不一定的)。第二个<code>script</code>元素的代码必须在第一个<code>script</code>元素的代码解释完毕才开始解释。以此类推。<code>script</code>元素内容的加载和解析都会阻止页面的渲染。</p><h2 id="_3-语言基础" tabindex="-1">3.语言基础 <a class="header-anchor" href="#_3-语言基础" aria-hidden="true">#</a></h2><h3 id="_3-3-变量" tabindex="-1">3.3 变量 <a class="header-anchor" href="#_3-3-变量" aria-hidden="true">#</a></h3><ul><li>在严格模式下，给未声明的变量赋值，会导致抛出<code>ReferenceError</code>错误。</li><li>在严格模式下，不能定义名为<code>eval</code>和<code>arguments</code>的变量，否则会导致语法错误。</li><li>有三个关键字可以声明变量<code>var,let,const</code></li></ul><h4 id="_1-var-声明提升" tabindex="-1">1.var 声明提升 <a class="header-anchor" href="#_1-var-声明提升" aria-hidden="true">#</a></h4><p><code>var</code>关键字声明的变量会自动提升到函数作用域顶部，如下面代码不会报错：</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">foo</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">cosole</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">age</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">var</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">age</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#F78C6C;">28</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#82AAFF;">foo</span><span style="color:#A6ACCD;">() </span><span style="color:#676E95;font-style:italic;">// undefined</span></span>
<span class="line"></span></code></pre></div><p>上面示例结果为 undefined，之所以不会报错，其实它声明提升后等价于如下代码：</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">foo</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">var</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">age</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">cosole</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">age</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">age</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#F78C6C;">28</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#82AAFF;">foo</span><span style="color:#A6ACCD;">() </span><span style="color:#676E95;font-style:italic;">// undefined</span></span>
<span class="line"></span></code></pre></div><p>以上就是所谓的&quot;提升&quot;（hoist），也就是把所有变量声明都拉到函数作用域的顶部。</p><h4 id="_2-let-声明" tabindex="-1">2.let 声明 <a class="header-anchor" href="#_2-let-声明" aria-hidden="true">#</a></h4><p><code>let</code>和<code>var</code>的作用差不多，但有非常重要的区别。最明显的区别是，<code>let</code>声明的范围是块作用域(<code>{}</code>中)，而<code>var</code>声明的范围是函数作用域。</p><ul><li><p>暂时性死区</p><p><code>let</code>与<code>var</code>的另一个重要的区别，就是 let 声明的变量不会在作用域中被提升。</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(age) </span><span style="color:#676E95;font-style:italic;">//ReferenceError:age未定义</span></span>
<span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> age </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">28</span></span>
<span class="line"></span></code></pre></div><p>在<code>let</code>声明之前的执行瞬间被称为&quot;暂时性死区&quot;(temporal dead zone)，在此阶段引用任何后面才声明的变量都会抛出<code>ReferenceError</code>。</p></li><li><p>全局声明</p><p>与 var 关键字不同，使用<code>let</code>在全局作用域中声明的变量不会成为<code>window</code>对象的属性。</p></li><li><p>for 循环中的 let 声明</p><p>看下面示例：</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#89DDFF;font-style:italic;">for</span><span style="color:#A6ACCD;"> (</span><span style="color:#C792EA;">var</span><span style="color:#A6ACCD;"> i </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0</span><span style="color:#89DDFF;">;</span><span style="color:#A6ACCD;"> i </span><span style="color:#89DDFF;">&lt;</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">5</span><span style="color:#89DDFF;">;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">++</span><span style="color:#A6ACCD;">i) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#82AAFF;">setTimeout</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">()</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">i</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#F78C6C;">0</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 输出： 5 5 5 5 5</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">for</span><span style="color:#A6ACCD;"> (</span><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> i </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0</span><span style="color:#89DDFF;">;</span><span style="color:#A6ACCD;"> i </span><span style="color:#89DDFF;">&lt;</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">5</span><span style="color:#89DDFF;">;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">++</span><span style="color:#A6ACCD;">i) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#82AAFF;">setTimeout</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">()</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">i</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#F78C6C;">0</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 输出：0 1 2 3 4</span></span>
<span class="line"></span></code></pre></div><p>为什么会这样，var 声明的 i 变量，保存的是循环退出的值 5。在之后的超时逻辑中，所有的 i 都是同一个变量 i。</p><p>而使用<code>let</code>声明迭代变量时，js 引擎在后台会为每一个迭代循环声明一个新的迭代变量，每个 setTimeout 引用的是不同变量实例</p><p>这种声明独立变量实例的行为适用于所有风格的<code>for</code>循环，包括<code>for-in</code>和<code>for of</code>循环。</p></li></ul><h4 id="_3-const-声明" tabindex="-1">3.const 声明 <a class="header-anchor" href="#_3-const-声明" aria-hidden="true">#</a></h4><p><code>const</code>的行为与 let 基本相同，唯一一个重要的区别是用它声明变量时必须同时初始化变量，且尝试修改<code>const</code>声明的变量会导致运行时错误。</p><p>如果 const 引用的是一个引用类型（如对象、数组），那么修改这个对象内部的属性并不违反 const 的限制</p><h4 id="_4-最佳实践" tabindex="-1">4.最佳实践 <a class="header-anchor" href="#_4-最佳实践" aria-hidden="true">#</a></h4><ul><li><p>不使用 <code>var</code></p><p>只使用<code>let</code>和<code>const</code>有助于提升代码质量，因为变量有了明确的作用域、声明位置和不变的值。</p></li><li><p><code>const</code>优先，<code>let</code>次之</p><p>使用<code>const</code>声明可以让浏览器运行时强制保持变量不变，也可以让静态代码分析工具提前发现不合法的赋值操作。</p></li></ul><h3 id="_3-4-数据类型" tabindex="-1">3.4 数据类型 <a class="header-anchor" href="#_3-4-数据类型" aria-hidden="true">#</a></h3><p>EcmaScript 有 6 种简单数据类型（也叫<strong>原始类型</strong>）：<code>Undefined</code>、<code>Null</code>、<code>Boolean</code>、<code>Number</code>、<code>String</code>、<code>Symbol</code>。 其中<code>Symbol</code>是 es6 新增的。</p><p>还有一种复杂的数据类型<code>Object</code>。</p><h4 id="_1-typeof-操作符" tabindex="-1">1.typeof 操作符 <a class="header-anchor" href="#_1-typeof-操作符" aria-hidden="true">#</a></h4><p><code>typeof</code>操作符会返回下列 7 种字符串之一:</p><ul><li><code>undefined</code>表示值未定义</li><li><code>boolean</code>表示值为布尔值</li><li><code>string</code>值为字符串</li><li><code>number</code>值为数值</li><li><code>object</code>表示值为对象或<code>null</code>，而不是函数</li><li><code>function</code>值为函数</li><li><code>symbol</code>值为符号</li></ul><p>特殊值<code>null</code>被认为是一个对空对象的引用。</p><p>另外要更进一步区分<code>object</code>类型，可以看如下示例：</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#676E95;font-style:italic;">// 以下是分别区分数组、对象和null</span></span>
<span class="line"><span style="color:#FFCB6B;">Object</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">prototype</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">toString</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">call</span><span style="color:#A6ACCD;">([]) </span><span style="color:#676E95;font-style:italic;">// &quot;[object Array]&quot;</span></span>
<span class="line"><span style="color:#FFCB6B;">Object</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">prototype</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">toString</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">call</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">{}</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// &quot;[object Object]&quot;</span></span>
<span class="line"><span style="color:#FFCB6B;">Object</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">prototype</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">toString</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">call</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">null</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// &quot;[object Null]&quot;</span></span>
<span class="line"></span></code></pre></div><h4 id="_2-undefined-类型" tabindex="-1">2.Undefined 类型 <a class="header-anchor" href="#_2-undefined-类型" aria-hidden="true">#</a></h4><p>Undefined 类型只有一个值：<code>undefined</code></p><ul><li>定义变量未赋初始值时，相当于给变量赋予了 undefined 值</li><li>未初始化的变量和未定义变量是有区别的</li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> message</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(message) </span><span style="color:#676E95;font-style:italic;">// undefined</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(message2) </span><span style="color:#676E95;font-style:italic;">// ReferenceError:message2 is not defined</span></span>
<span class="line"></span></code></pre></div><ul><li>未声明和未赋初始值对于 typeof 操作法都返回<code>undefined</code></li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> message</span></span>
<span class="line"><span style="color:#89DDFF;">typeof</span><span style="color:#A6ACCD;"> message </span><span style="color:#676E95;font-style:italic;">// &quot;undefined&quot;</span></span>
<span class="line"><span style="color:#89DDFF;">typeof</span><span style="color:#A6ACCD;"> message2 </span><span style="color:#676E95;font-style:italic;">// &quot;undefined&quot;</span></span>
<span class="line"></span></code></pre></div><blockquote><p><strong>注意</strong>：即使未赋初始值会自动赋予 undefined 值，也推荐初始化变量，这样档 typeof 操作法返回&quot;undefined&quot;时，我们知道该变量是未声明的，而不是声明了但未初始化</p></blockquote><h4 id="_3-null-类型" tabindex="-1">3.Null 类型 <a class="header-anchor" href="#_3-null-类型" aria-hidden="true">#</a></h4><ul><li>只有一个 null 值，表示空对象指针</li><li><code>typeof null</code>为 object</li><li>未来保存对象的变量，建议用 null 初始化，这样只需判断变量是否为 null<code>obj != null</code></li><li><code>null == undefined</code>为 true</li></ul><h4 id="_4-boolean-类型" tabindex="-1">4.Boolean 类型 <a class="header-anchor" href="#_4-boolean-类型" aria-hidden="true">#</a></h4><ul><li>有两个字面值：true 和 false</li><li>要将一个其它类型的值转化为布尔值，可以调用<code>Boolean()</code>函数</li><li>像 if 等控制流语句会自动进行转换</li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> message </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">hello</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#A6ACCD;"> (message) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">  </span><span style="color:#676E95;font-style:italic;">// 会执行</span></span>
<span class="line"><span style="color:#89DDFF;">  </span><span style="color:#676E95;font-style:italic;">// 因为Boolean(&quot;hello&quot;)为true</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span></code></pre></div><h4 id="_5-number-类型" tabindex="-1">5.Number 类型 <a class="header-anchor" href="#_5-number-类型" aria-hidden="true">#</a></h4><p>js 中<code>Number</code>类型使用 IEEE 754 格式表示整数和浮点值，也叫双精度值。</p><h5 id="_1-0-1-0-2-0-3" tabindex="-1">1. 0.1+0.2！==0.3 <a class="header-anchor" href="#_1-0-1-0-2-0-3" aria-hidden="true">#</a></h5><p>浮点值在算术计算中远不如整数精确。例如 0.1+0.2 得不到 0.3，而是 0.300 000 000 000 000 04。所以你不能像下面这样判断浮点值：</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#A6ACCD;"> (a </span><span style="color:#89DDFF;">+</span><span style="color:#A6ACCD;"> b </span><span style="color:#89DDFF;">==</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0.3</span><span style="color:#A6ACCD;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">  </span><span style="color:#676E95;font-style:italic;">// 别这么干</span></span>
<span class="line"><span style="color:#89DDFF;">  </span><span style="color:#676E95;font-style:italic;">//...</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span></code></pre></div><p>解决方式其中一种是使用<code>toFixed()</code>方法精确小数位数。</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#82AAFF;">parseFloat</span><span style="color:#A6ACCD;">(</span><span style="color:#FFCB6B;">Number</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">prototype</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">toFixed</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">call</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">0.1</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">+</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0.2</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">8</span><span style="color:#A6ACCD;">)) </span><span style="color:#676E95;font-style:italic;">// 0.3</span></span>
<span class="line"></span></code></pre></div><h5 id="_2-值的范围" tabindex="-1">2.值的范围 <a class="header-anchor" href="#_2-值的范围" aria-hidden="true">#</a></h5><ul><li>js 能表示的最小和最大值存储在<code>Number.MIN_VALUE和Number.MAX_VALUE</code>中</li><li>超出了范围则会用特殊值表示<code>Infinity和-Infinity</code></li><li>查看一个数是否是有穷的可通过<code>isFinite()</code>方法</li></ul><h5 id="_3-nan-not-a-number" tabindex="-1">3.NaN(Not a Number) <a class="header-anchor" href="#_3-nan-not-a-number" aria-hidden="true">#</a></h5><ul><li><code>NaN</code>不等于包括 NaN 在内的任何值，如下</li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#89DDFF;">NaN</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">==</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">NaN</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">// false</span></span>
<span class="line"></span></code></pre></div><ul><li>任何涉及 NaN 的操作都返回 NaN</li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#89DDFF;">NaN</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">/</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">10</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">// NaN</span></span>
<span class="line"></span></code></pre></div><ul><li>可通过<code>isNaN()</code>方法判断是否&#39;不是一个数值&#39;</li></ul><h5 id="_4-数值转换" tabindex="-1">4.数值转换 <a class="header-anchor" href="#_4-数值转换" aria-hidden="true">#</a></h5><p>有 3 个函数可以将非数值转换为数值：<code>Number()</code>、<code>parseInt()</code>、<code>parseFloat()</code>。</p><p>其中<code>Number</code>转换规则最为复杂，<code>parseInt</code>和<code>parseFloat</code>专注于转换字符串。</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#82AAFF;">parseInt</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">123blue</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// 123</span></span>
<span class="line"><span style="color:#82AAFF;">parseInt</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;&quot;</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// NaN</span></span>
<span class="line"><span style="color:#82AAFF;">parseInt</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">22.5</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// 22</span></span>
<span class="line"><span style="color:#82AAFF;">parseInt</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">77</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// 77</span></span>
<span class="line"><span style="color:#82AAFF;">parseInt</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">AF</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">16</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// 175</span></span>
<span class="line"><span style="color:#82AAFF;">parseInt</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">{</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">toString</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">23</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// 23</span></span>
<span class="line"></span>
<span class="line"><span style="color:#82AAFF;">parseInt</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">2.6.4</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// 2</span></span>
<span class="line"><span style="color:#82AAFF;">parseFloat</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">2.6.4</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// 2.6</span></span>
<span class="line"></span></code></pre></div><p>Number 转换规则如下：</p><ul><li>数值：直接返回</li><li>布尔值：true 返回 1，false 返回 0</li><li>null：返回 0</li><li>undefined：返回 NaN</li><li>字符串： <ul><li>如果字符串都为数字组成，包括前面的+-符号，则返回十进制数值</li><li>如果字符串包含正确的浮点格式，则转换为浮点值</li><li>如果字符串是有效的十六进制格式，则转换为该十六进制对应的十进制数值</li><li>如果是空字符串，返回 0</li><li>如果以上都不是，返回 NaN</li></ul></li><li>对象： <ul><li>先调用<code>valueOf()</code>方法，按照上述规则进行转换，如果返回 NaN，则调用<code>toString()</code>方法继续转换</li></ul></li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#82AAFF;">Number</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">11</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// 11</span></span>
<span class="line"><span style="color:#82AAFF;">Number</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">11a</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// NaN</span></span>
<span class="line"><span style="color:#82AAFF;">Number</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">0xf</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// 15</span></span>
<span class="line"><span style="color:#82AAFF;">Number</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">{</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">toString</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">2</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// 2</span></span>
<span class="line"></span></code></pre></div><h4 id="_6-string-类型" tabindex="-1">6.String 类型 <a class="header-anchor" href="#_6-string-类型" aria-hidden="true">#</a></h4><h5 id="_1-字符字面量" tabindex="-1">1.字符字面量 <a class="header-anchor" href="#_1-字符字面量" aria-hidden="true">#</a></h5><ul><li><code>\xnn</code>表示以十六进制 nn 表示的字符，如<code>\x41</code>表示 A</li><li><code>\unnnn</code>表示以十六进制 nnnn 表示的 Unicode 字符，如<code>\u03a3</code> 等于希腊字符&quot;Σ&quot;</li></ul><h5 id="_2-转换为字符串" tabindex="-1">2.转换为字符串 <a class="header-anchor" href="#_2-转换为字符串" aria-hidden="true">#</a></h5><p>几乎所有值都有<code>toString()</code>方法，常见的如数值、布尔值、对象和字符串值。<code>null</code>和<code>undefined</code>值没有 toString 方法，建议提前使用<code>a == null</code>判断下是否是<code>null</code>或<code>undefined</code>值再使用<code>toString()</code>方法。或者使用<code>String()</code>函数，它会先确定是否有<code>toString()</code>方法，如果是<code>null</code>或<code>undefined</code>则会返回对应的字符串形式<code>&quot;null&quot;或&quot;undefined&quot;</code></p><p>大多数情况下，<code>toString()</code>没有任何参数，不过，在对数值调用<code>toString()</code>方法时，可以接收一个底数，表示以什么底数来输出数值的字符串表示。默认是十进制。</p><blockquote><p>此方法可用作 10 进制数值转其它进制数值，另外其它进制数值转 10 进制可以使用<code>parseInt()</code>方法，指定第二个参数。</p></blockquote><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> age </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">11</span></span>
<span class="line"><span style="color:#A6ACCD;">age</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">toString</span><span style="color:#A6ACCD;">() </span><span style="color:#676E95;font-style:italic;">// &quot;11&quot;</span></span>
<span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> found </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#FF9CAC;">true</span></span>
<span class="line"><span style="color:#A6ACCD;">found</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">toString</span><span style="color:#A6ACCD;">() </span><span style="color:#676E95;font-style:italic;">// &quot;true&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> num </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">10</span></span>
<span class="line"><span style="color:#A6ACCD;">num</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">toString</span><span style="color:#A6ACCD;">() </span><span style="color:#676E95;font-style:italic;">// &quot;10&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">num</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">toString</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">2</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// &quot;1010&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">num</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">toString</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">16</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// &quot;a&quot;</span></span>
<span class="line"></span></code></pre></div><p><code>String()</code>方法遵循如下规则：</p><ul><li>首先看值是否有 <code>toString()</code> 方法，有则调用该方法并返回结果</li><li>如果是 null，返回&quot;null&quot;</li><li>如果是 undefined，返回&quot;undefined&quot;</li></ul><h4 id="_7-symbol-类型" tabindex="-1">7.Symbol 类型 <a class="header-anchor" href="#_7-symbol-类型" aria-hidden="true">#</a></h4><ul><li>符号用来创建唯一记号，进而用作非字符串形式的对象属性。</li><li>符号实例是唯一的，不可变的</li><li>符号的用途是确保对象属性使用唯一标志，不会发生属性冲突的危险</li></ul><h5 id="_1-常用内置符号" tabindex="-1">1.常用内置符号 <a class="header-anchor" href="#_1-常用内置符号" aria-hidden="true">#</a></h5><p>es6 引入了一批常用的内置符号，用于暴露语言内部行为。开发者可以重写、访问或模拟这些行为。</p><p>这些符号的最重要用途之一就是重新定义它们，从而改变原生结构的行为。比如我们知道<code>for-of</code>循环会在相关对象上使用<code>Symbol.iterator</code>属性，那么就可以通过在自定义对象上重新定义<code>Symbol.iterator</code>的值，来改变<code>for-of</code>在迭代该对象时的行为。</p><p>这些内置符号也没有什么特别之处，它们就是全局函数<code>Symbol</code>的普通字符串属性，<strong>指向一个符号的实例</strong>。所有内置符号属性都是不可写、不可枚举、不可配置的。</p><blockquote><p><strong>注意</strong> 在提到 ECMAScript 规范时，经常会引用符号在规范中的名称，前缀为<code>@@</code>。比如<code>@@iterator</code>指的就是<code>Symbol.iterator</code></p></blockquote><ul><li><p><code>Symbol.hasInstance</code></p><p>该符号作为一个属性表示“一个方法，该方法决定一个构造器对象是否认可一个对象是它的实例。由<code>instanceof</code>操作符使用”</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">Foo</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{}</span></span>
<span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> f </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">Foo</span><span style="color:#A6ACCD;">()</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(f </span><span style="color:#89DDFF;">instanceof</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">Foo</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// true</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(Foo[Symbol</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">hasInstance](f)) </span><span style="color:#676E95;font-style:italic;">// true</span></span>
<span class="line"></span></code></pre></div><p>该属性是定义在<code>Function</code>的原型上，因此默认在所有函数和类上都可以调用，当然你也可以重写这个函数。</p></li><li><p><code>Symbol.isConcatSpreadable</code></p><p>该符号作为一个属性表示“一个布尔值，如果是 true，则意味着对象应该用<code>Array.prototype.concat()</code>打平其数组元素”。数组对象默认情况下会被打平到已有的数组。</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> a </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> [</span><span style="color:#F78C6C;">1</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">2</span><span style="color:#A6ACCD;">]</span></span>
<span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> b </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> [</span><span style="color:#F78C6C;">3</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">4</span><span style="color:#A6ACCD;">]</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(b[Symbol</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">isConcatSpreadable]) </span><span style="color:#676E95;font-style:italic;">//undefined</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(a</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">concat</span><span style="color:#A6ACCD;">(b)) </span><span style="color:#676E95;font-style:italic;">// [1,2,3,4]  数组元素默认会被打平</span></span>
<span class="line"><span style="color:#A6ACCD;">b[Symbol</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">isConcatSpreadable] </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#FF9CAC;">false</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(a</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">concat</span><span style="color:#A6ACCD;">(b)) </span><span style="color:#676E95;font-style:italic;">// [1,2,Array(2)]  为false时，不打平</span></span>
<span class="line"><span style="color:#A6ACCD;">b[Symbol</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">isConcatSpreadable] </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#FF9CAC;">true</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(a</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">concat</span><span style="color:#A6ACCD;">(b)) </span><span style="color:#676E95;font-style:italic;">// [1,2,3,4]  为true时，打平</span></span>
<span class="line"></span></code></pre></div></li><li><p><code>Symbol.iterator</code></p><p>该符号作为一个属性表示“一个方法，该方法返回对象默认的迭代器。由<code>for-of</code>语句使用”。 迭代器将在第 7 章详细介绍。</p></li><li><p><code>Symbol.match</code></p><p>表示“一个正则表达式方法，由<code>String.prototype.match()</code>方法使用”</p></li><li><p><code>Symbol.replace</code></p><p>表示“一个正则表达式方法，由<code>String.prototype.replace()</code>方法使用”</p></li><li><p><code>Symbol.search</code></p><p>表示“一个正则表达式方法，由<code>String.prototype.search()</code>方法使用”</p></li><li><p><code>Symbol.split</code></p><p>表示“一个正则表达式方法，由<code>String.prototype.split()</code>方法使用”</p></li></ul><p>以上几个字符串的正则方法，都会调用传入的正则表达式的对应符号为键的方法，如果传入的为字符串，则会转换为<code>RegExp</code>对象。</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#676E95;font-style:italic;">//例如</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">foobarbaz</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">split</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">/</span><span style="color:#C3E88D;">bar</span><span style="color:#89DDFF;">/</span><span style="color:#A6ACCD;">))</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 其实类似于如下示例，会把原字符串foobarbaz作为参数</span></span>
<span class="line"><span style="color:#FFCB6B;">RegExp</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">prototype[Symbol</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">split]</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">call</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">/</span><span style="color:#C3E88D;">bar</span><span style="color:#89DDFF;">/</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">foobarbaz</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">//[&quot;foo&quot;, &quot;baz&quot;]</span></span>
<span class="line"></span></code></pre></div><ul><li><p><code>Symbol.toStringTag</code></p><p>由<code>Object.prototype.toString</code>使用。通过<code>toString()</code>方法获取对象标识时，会检索由<code>Symbol.toStringTag</code>指定的实例标识符，默认是<code>Object</code>。内置类型已经指定了这个值，自定义类实例则需要明确定义：</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">Bar</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#C792EA;">constructor</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">this</span><span style="color:#F07178;">[</span><span style="color:#A6ACCD;">Symbol</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">toStringTag</span><span style="color:#F07178;">] </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">Bar</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> bar </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">Bar</span><span style="color:#A6ACCD;">()</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(bar</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">toString</span><span style="color:#A6ACCD;">()) </span><span style="color:#676E95;font-style:italic;">// [object Bar]</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(bar[Symbol</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">toStringTag]) </span><span style="color:#676E95;font-style:italic;">// Bar</span></span>
<span class="line"></span></code></pre></div></li></ul><h4 id="_8-object-类型" tabindex="-1">8. Object 类型 <a class="header-anchor" href="#_8-object-类型" aria-hidden="true">#</a></h4><p><code>Object</code>是派生其它对象的基类。所有属性和方法在派生的对象上同样存在。</p><p>每个<code>Object</code>实例都有如下属性和方法。</p><ul><li><code>constructor</code>：用于创建当前对象的<strong>函数</strong>。</li><li><code>hasOwnProperty(propertyName)</code>：用于判断当前对象实例（不是原型）上是否存在给定的属性。</li><li><code>isPrototypeof(object)</code>：用于判断当前对象是否为另一个对象的原型。</li><li><code>propertyIsEnumerable(propertyName)</code>：用于判断给定的属性是否可以使用<code>for-in</code>语句枚举。</li><li><code>toLocalString()</code>：返回对象的字符串标识，该字符串反映对象所在的本地化执行环境。</li><li><code>toString()</code>：返回对象的字符串标识</li><li><code>valueOf()</code>：返回对象对应的字符串、数值或布尔值标识。通常和<code>toString()</code>的返回值相同。</li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> o </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">Object</span><span style="color:#A6ACCD;">()</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(o</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">constructor) </span><span style="color:#676E95;font-style:italic;">// function Object(){}</span></span>
<span class="line"></span></code></pre></div><blockquote><p><strong>注意</strong> BOM 和 DOM 对象，都是由宿主环境定义和提供的宿主对象，它不受 ECMA-262 约束，所以它们可能会也可能不会继承<code>Object</code></p></blockquote><h3 id="_3-5-操作符" tabindex="-1">3.5 操作符 <a class="header-anchor" href="#_3-5-操作符" aria-hidden="true">#</a></h3><h4 id="_1-一元加和减操作符" tabindex="-1">1.一元加和减操作符 <a class="header-anchor" href="#_1-一元加和减操作符" aria-hidden="true">#</a></h4><p>如果将一元加和减操作符运用到非数值，则会执行<code>Number()</code>转型函数一样的类型转换：布尔值<code>false</code>和<code>true</code>转换为 0 和 1，字符串根据特殊规则进行解析，对象会调用它们的<code>valueOf()</code>或<code>toString()</code>方法以得到可以转换的值。</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#A6ACCD;">+true //1</span></span>
<span class="line"><span style="color:#A6ACCD;">-true //-1</span></span>
<span class="line"><span style="color:#A6ACCD;">+{toString:()=&gt;&#39;123&#39;} // 123</span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span></code></pre></div><h4 id="_2-位操作符" tabindex="-1">2.位操作符 <a class="header-anchor" href="#_2-位操作符" aria-hidden="true">#</a></h4><ul><li><code>~</code>:按位非，每个二进制位取反，相当于对数值取反并减一</li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> n </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">25</span></span>
<span class="line"><span style="color:#89DDFF;">~</span><span style="color:#A6ACCD;">n </span><span style="color:#676E95;font-style:italic;">// -26</span></span>
<span class="line"></span></code></pre></div><ul><li><code>&amp;</code>:按位与，两个值的二进制位对齐，都是 1 则得 1，其它为 0</li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#F78C6C;">25</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&amp;</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">3</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">// 1</span></span>
<span class="line"></span></code></pre></div><ul><li><code>|</code>:按位或，有一个为 1 则为 1，两个都是 0 则为 0</li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#F78C6C;">25</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">|</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">3</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">// 27</span></span>
<span class="line"></span></code></pre></div><ul><li><code>^</code>:按位异或，两个位都相同则为 0，不同则为 1</li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#F78C6C;">25</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">^</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">3</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">// 26</span></span>
<span class="line"></span></code></pre></div><ul><li><code>&lt;&lt;</code>:左移，将数值按指定的位数向左移动</li><li>左移后，右端空出的会以 0 填充</li><li>左移会保留数值的符号</li></ul><div class="language-c"><button title="Copy Code" class="copy"></button><span class="lang">c</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#F78C6C;">2</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&lt;&lt;</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1</span><span style="color:#676E95;font-style:italic;"> // 4</span></span>
<span class="line"><span style="color:#F78C6C;">2</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&lt;&lt;</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">2</span><span style="color:#676E95;font-style:italic;"> // 8</span></span>
<span class="line"><span style="color:#F78C6C;">2</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&lt;&lt;</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">3</span><span style="color:#676E95;font-style:italic;"> // 16</span></span>
<span class="line"><span style="color:#89DDFF;">-</span><span style="color:#F78C6C;">2</span><span style="color:#89DDFF;">&lt;&lt;</span><span style="color:#F78C6C;">1</span><span style="color:#676E95;font-style:italic;"> // -4</span></span>
<span class="line"></span></code></pre></div><ul><li><code>&gt;&gt;</code>:有符号右移</li><li>有符号右移会将所有 32 为右移，同时保留符号（正负）</li><li>有符号右移实际是左移的逆运算</li><li>右移后左侧有空位，会用符号位的值填充空位</li></ul><div class="language-c"><button title="Copy Code" class="copy"></button><span class="lang">c</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#F78C6C;">16</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&gt;&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">3</span><span style="color:#676E95;font-style:italic;"> // 2</span></span>
<span class="line"><span style="color:#89DDFF;">-</span><span style="color:#F78C6C;">4</span><span style="color:#89DDFF;">&gt;&gt;</span><span style="color:#F78C6C;">1</span><span style="color:#676E95;font-style:italic;"> // -2</span></span>
<span class="line"></span></code></pre></div><ul><li><code>&gt;&gt;&gt;</code>:无符号右移</li><li>有符号右移会将所有 32 为右移</li><li>对于正数，无符号右移和有符号右移一样</li><li>对于负数，结果相差很大。因为无符号右移，只会给左边空位补 0，而不管符号为是什么</li></ul><div class="language-c"><button title="Copy Code" class="copy"></button><span class="lang">c</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#F78C6C;">16</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&gt;&gt;&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">3</span><span style="color:#676E95;font-style:italic;"> // 2</span></span>
<span class="line"><span style="color:#89DDFF;">-</span><span style="color:#F78C6C;">4</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&gt;&gt;&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1</span><span style="color:#676E95;font-style:italic;"> // 2147483646</span></span>
<span class="line"></span></code></pre></div><h4 id="_3-布尔操作符" tabindex="-1">3.布尔操作符 <a class="header-anchor" href="#_3-布尔操作符" aria-hidden="true">#</a></h4><p>同时使用两个叹号(<code>!!</code>)，相当于调用了转型函数<code>Boolean()</code>。</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#89DDFF;">!!</span><span style="color:#F78C6C;">0</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">// false</span></span>
<span class="line"></span></code></pre></div><h4 id="_4-关系操作符" tabindex="-1">4.关系操作符 <a class="header-anchor" href="#_4-关系操作符" aria-hidden="true">#</a></h4><p>当字符串和字符串比较时，实际比较的是字符串挨个的编码。 如下，因为 B 的字符编码 66 是小于 a 的编码 97 的。</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">Brick</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&lt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">alphabet</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">// true</span></span>
<span class="line"></span></code></pre></div><p>当有一个是数字时，会把另一个也转换位数值，再比较。</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">23</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&lt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">3</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">// true  2的字符编码50和3的字符编码51相比较</span></span>
<span class="line"><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">23</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&lt;</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">3</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">// false  转换成了23 &lt; 3</span></span>
<span class="line"></span></code></pre></div><h4 id="_5-加性操作法" tabindex="-1">5.加性操作法 <a class="header-anchor" href="#_5-加性操作法" aria-hidden="true">#</a></h4><p>加操作符</p><ul><li>如果两个都是字符串，则拼接在一起</li><li>如果只有一个是字符串，则另一个转成字符串再拼接</li><li>对于 undefined 和 null，则调用 String 函数获取字符串形式</li></ul><p>减操作符</p><ul><li>如果有任意操作数是字符串、undefined、null 或布尔值，则调用 Number 转换为数字</li><li>如果有任意操作数为对象，则调用 valueOf 方法取数值，如果为 NaN，则返回 NaN。如果没有 valueOf 方法，则调用 toString 方法，再将字符串转为数字</li></ul><h4 id="_6-相等操作符" tabindex="-1">6.相等操作符 <a class="header-anchor" href="#_6-相等操作符" aria-hidden="true">#</a></h4><ul><li>等于和不等于</li></ul><p>等于(<code>==</code>)和不等于(<code>!=</code>)，如果两个操作数类型不同，会先进行类型转换（即<strong>强制类型转换</strong>），再确定操作数是否相等。</p><p>在转换时遵循如下规则：</p><ul><li>任一操作符是布尔值，则将其转换为数值进行比较。</li><li>一个操作符是字符串，另一个是数值，则将字符串转换为数值，再比较</li><li>如果一个操作数是对象，另一个不是，则调用对象的<code>valueOf()</code>方法取其原始值，再根据前面规则进行比较。</li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#FF9CAC;">false</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">==</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">// true</span></span>
<span class="line"><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">2</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">==</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">2</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">// true</span></span>
<span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> obj </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">valueOf</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">2</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">obj </span><span style="color:#89DDFF;">==</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">2</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">// true</span></span>
<span class="line"></span></code></pre></div><p>在进行比较时，还遵循如下规则</p><ul><li><code>null</code>和<code>undefined</code>相等</li><li><code>null</code>和<code>undefined</code>不能转换为其它类型的值进行比较</li><li><code>NaN</code>不和任一值相等</li><li>如果两个操作数都是对象，则比较它们是不是同一个对象。是返回 true，否则返回 false。</li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#89DDFF;">NaN</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">==</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">NaN</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">// false</span></span>
<span class="line"><span style="color:#89DDFF;">NaN</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">!=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">// true</span></span>
<span class="line"><span style="color:#89DDFF;">undefined</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">==</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">// false  null和undefined不能转换为其它类型</span></span>
<span class="line"><span style="color:#89DDFF;">null</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">==</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">undefined</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">// true</span></span>
<span class="line"><span style="color:#FF9CAC;">true</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">==</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">// true  true会转换为1，false会转换为0</span></span>
<span class="line"><span style="color:#FF9CAC;">true</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">==</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">2</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">// false</span></span>
<span class="line"></span></code></pre></div><h3 id="_3-6-语句" tabindex="-1">3.6 语句 <a class="header-anchor" href="#_3-6-语句" aria-hidden="true">#</a></h3><h4 id="_1-for-in-语句" tabindex="-1">1.for...in 语句 <a class="header-anchor" href="#_1-for-in-语句" aria-hidden="true">#</a></h4><p>用于枚举对象中的非符号键属性</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#89DDFF;font-style:italic;">for</span><span style="color:#A6ACCD;"> (</span><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> propName </span><span style="color:#89DDFF;">in</span><span style="color:#A6ACCD;"> window) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">propName</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span></code></pre></div><h4 id="_2-for-of-语句" tabindex="-1">2.for...of 语句 <a class="header-anchor" href="#_2-for-of-语句" aria-hidden="true">#</a></h4><p>用于遍历<strong>可迭代对象</strong>的 元素</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#89DDFF;font-style:italic;">for</span><span style="color:#A6ACCD;"> (</span><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> ele </span><span style="color:#89DDFF;">of</span><span style="color:#A6ACCD;"> [</span><span style="color:#F78C6C;">2</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">3</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">4</span><span style="color:#A6ACCD;">]) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">ele</span><span style="color:#F07178;">) </span><span style="color:#676E95;font-style:italic;">// 2 3 4</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span></code></pre></div><h2 id="_4-变量、作用域与内存" tabindex="-1">4.变量、作用域与内存 <a class="header-anchor" href="#_4-变量、作用域与内存" aria-hidden="true">#</a></h2><h3 id="_4-1-原始值与引用" tabindex="-1">4.1 原始值与引用 <a class="header-anchor" href="#_4-1-原始值与引用" aria-hidden="true">#</a></h3><h4 id="_1-复制值" tabindex="-1">1. 复制值 <a class="header-anchor" href="#_1-复制值" aria-hidden="true">#</a></h4><ul><li>把引用值从一个变量赋给另一个变量时，实际上复制的是指针，这个指针都指向存储在堆内存中的对象</li></ul><h4 id="_2-传递参数" tabindex="-1">2. 传递参数 <a class="header-anchor" href="#_2-传递参数" aria-hidden="true">#</a></h4><p>在 js 中，所有函数的参数都是<strong>按值传递的</strong>。这意味着函数外的值，会被复制到函数内部的参数中。</p><h3 id="_4-2-执行上下文与作用域" tabindex="-1">4.2 执行上下文与作用域 <a class="header-anchor" href="#_4-2-执行上下文与作用域" aria-hidden="true">#</a></h3><p>每个函数调用都有自己的执行上下文，当执行到该函数时，它的执行上下文会被推入到一个上下文栈中</p><p>每个上下文都有一个关联的<strong>变量对象（variable object）</strong>，在这个上下文中定义的变量和函数，都存储在这个对象上</p><p>上下文在其执行完毕后，会被销毁，包括定义在它上面的变量和函数（全局上下文只有在网页关闭时才会销毁）（闭包是另一种情形）</p><p>上下文的代码在执行时，会创建变量对象的一个作用域链（scope chain），代码正在执行的上下文的变量对象始终位于作用域链的最前端</p><p>作用域链的下一个对象来自包含上下文，再下一个对象来自再下一个包含上下文。以此类推，直至全局上下文。</p><p>代码执行时，标识符解析是通过沿作用域链逐级搜索标识符名称完成的。</p><h3 id="_4-3-垃圾回收" tabindex="-1">4.3 垃圾回收 <a class="header-anchor" href="#_4-3-垃圾回收" aria-hidden="true">#</a></h3><h4 id="_1-标记清理" tabindex="-1">1.标记清理 <a class="header-anchor" href="#_1-标记清理" aria-hidden="true">#</a></h4><p>标记清理（mark-and-sweep），js 最常用的垃圾回收策略</p><p>垃圾回收程序运行时，会标记内存中存储的所有变量（标记方法有多种）</p><p>然后它会将所有在上下文中的变量，以及上下文中变量引用的变量的标记去掉，此操作后还有标记的就是待删除的了。因为任何上下文的变量都访问不到它们了。</p><h4 id="_2-引用计数" tabindex="-1">2.引用计数 <a class="header-anchor" href="#_2-引用计数" aria-hidden="true">#</a></h4><p>没那么常用，容易出问题，如造成循环引用。</p><h4 id="_4-内存管理" tabindex="-1">4.内存管理 <a class="header-anchor" href="#_4-内存管理" aria-hidden="true">#</a></h4><ul><li>优化内存占用的最佳手段是，保证在执行时代码只保存必要的数据，如果数据不必要，则置为 null</li><li>避免 js 先创建再补充式的动态属性赋值，如针对对象，最好先定义好所有需要的属性，避免在之后动态增减键</li><li>静态分配属于极端形式，很多时候属于过早优化，不用过早考虑</li></ul><h2 id="_5-基本引用类型" tabindex="-1">5.基本引用类型 <a class="header-anchor" href="#_5-基本引用类型" aria-hidden="true">#</a></h2><p>对象被认为是某个特定引用类型的<strong>实例</strong>。新对象通过使用<code>new</code>操作符后跟一个<strong>构造函数</strong>(constructor)来创建。构造函数就是用来<strong>创建新对象</strong>的<strong>函数</strong>。</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> now </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">Date</span><span style="color:#A6ACCD;">()</span></span>
<span class="line"></span></code></pre></div><h3 id="_5-1date" tabindex="-1">5.1Date <a class="header-anchor" href="#_5-1date" aria-hidden="true">#</a></h3><p><code>getTimezoneOffset()</code>，返回以分钟计的 UTC 与本地时区的偏移量, 比如中国时区是 GMT+8，即 UTC 时间+8 个小时，那么<code>getTimezoneOffset</code>会返回<code>-480</code>。</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> now </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">Date</span><span style="color:#A6ACCD;">()</span></span>
<span class="line"><span style="color:#A6ACCD;">now</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getTimezoneOffset</span><span style="color:#A6ACCD;">() </span><span style="color:#676E95;font-style:italic;">// -480</span></span>
<span class="line"></span></code></pre></div><h4 id="_1-日期-时间组件方法" tabindex="-1">1.日期/时间组件方法 <a class="header-anchor" href="#_1-日期-时间组件方法" aria-hidden="true">#</a></h4><p>常用方法如下：</p><ul><li>getFullYear()，返回 4 位数年</li><li>getMonth()，返回月（0 表示 1 月，11 表示 12 月）</li><li>getDate()，返回日（1-31）</li><li>getHours()，返回时（0-23）</li><li>getMinutes()，返回分（0-59）</li><li>getSeconds()，返回秒（0-59）</li><li>getDay()，返回周几数字（0 表示周日，6 表示周六）</li></ul><h3 id="_5-3-原始值包装类型" tabindex="-1">5.3 原始值包装类型 <a class="header-anchor" href="#_5-3-原始值包装类型" aria-hidden="true">#</a></h3><p>原始值理论上是不能有方法的，但为什么我们能用呢？比如字符串的<code>(&#39;sss&#39;).substring(1)</code></p><p>这是因为，每当用到原始值的方法或属性时，后台都会创建一个相应原始包装类型的对象，供调用，调用完毕后销毁此对象</p><p>如下：</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> s1 </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">some text</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> s2 </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> s1</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">substring</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">2</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"></span></code></pre></div><p>s1 相当于做了如下操作：</p><ul><li>创建一个 String 类型的实例</li><li>调用实例上的方法</li><li>销毁实例</li></ul><p>对布尔值和数值同理，只不过使用的是<code>Boolean</code>和<code>Number</code>包装类型</p><h4 id="_1-boolean" tabindex="-1">1.Boolean <a class="header-anchor" href="#_1-boolean" aria-hidden="true">#</a></h4><p>一般用不到，要注意到的是，用包装类型创建的实例是一个对象，原始值则不是</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> falseObj </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">Boolean</span><span style="color:#A6ACCD;">(</span><span style="color:#FF9CAC;">false</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> falseValue </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#FF9CAC;">false</span></span>
<span class="line"><span style="color:#89DDFF;">typeof</span><span style="color:#A6ACCD;"> falseObj </span><span style="color:#676E95;font-style:italic;">// object</span></span>
<span class="line"><span style="color:#89DDFF;">typeof</span><span style="color:#A6ACCD;"> falseValue </span><span style="color:#676E95;font-style:italic;">// boolean</span></span>
<span class="line"><span style="color:#A6ACCD;">falseObj </span><span style="color:#89DDFF;">instanceof</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">Boolean</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">// true</span></span>
<span class="line"><span style="color:#A6ACCD;">falseValue </span><span style="color:#89DDFF;">instanceof</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">Boolean</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">// false</span></span>
<span class="line"></span></code></pre></div><h4 id="_2-number" tabindex="-1">2.Number <a class="header-anchor" href="#_2-number" aria-hidden="true">#</a></h4><p>Number 类型重写了<code>valueOf、toString</code>等方法，还提供了一些其它格式化为字符串的方法</p><ul><li>toString</li></ul><p>toString 方法可以接收一个基数，并返回相应基数形式的数值字符串，默认是 10</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> num </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">10</span></span>
<span class="line"><span style="color:#A6ACCD;">num</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">toString</span><span style="color:#A6ACCD;">() </span><span style="color:#676E95;font-style:italic;">// &quot;10&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">num</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">toString</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">2</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// &quot;1010&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">num</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">toString</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">16</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// &quot;a&quot;</span></span>
<span class="line"></span></code></pre></div><ul><li>toFixed</li></ul><p>toFixed 返回包含指定小数点位数的数值字符串，一般支持 0-20 个小数位</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> num </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0</span></span>
<span class="line"><span style="color:#A6ACCD;">num</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">toFixed</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">2</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// &quot;10.00&quot;</span></span>
<span class="line"></span></code></pre></div><ul><li>Number.isInteger()</li></ul><p>es6 新增，辨别一个数值是否保存为整数</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#A6ACCD;">Number</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">isInteger</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">1.0</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// true</span></span>
<span class="line"><span style="color:#A6ACCD;">Number</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">isInteger</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">1.01</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// false</span></span>
<span class="line"></span></code></pre></div><ul><li>Number.isSafeInteger()</li></ul><p>表示值是否在 <code>Number.MIN_SAFE_INTEGER</code> <code>（-2**53 + 1）</code> 到 <code>Number.MAX_SAFE_INTEGER</code> <code>（2**53-1）</code>之间</p><p>如果不在这之间，可能存储结果和实际结果完全不一样了</p><h4 id="_3-string" tabindex="-1">3.String <a class="header-anchor" href="#_3-string" aria-hidden="true">#</a></h4><p>String 类型提供了很多方法来解析和操作字符串</p><ul><li>length 属性</li></ul><p>每个<code>String</code>对象都有一个 length 属性，标识字符串中字符得数量。注意，即使字符串中包含<strong>双字节</strong>（而不是单字节的 ASCII 字符），也仍然会按单字符来计算。</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> strValue </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">hello你好</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">strValue</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">length </span><span style="color:#676E95;font-style:italic;">// 7</span></span>
<span class="line"></span></code></pre></div><ul><li>chartAt 方法</li></ul><p>charAt 方法返回给定索引位置的字符</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> m </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">abcde</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">m</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">charAt</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">2</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">//c</span></span>
<span class="line"></span></code></pre></div><ul><li>charCodeAt 方法</li></ul><p>方法返回指定索引位置的码元值</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> m </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">abcde</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">m</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">charCodeAt</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">2</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// 99</span></span>
<span class="line"></span></code></pre></div><ul><li>fromCharCode 方法</li></ul><p>用于根据给定的 UTF-16 码元创建字符，可接受多个数值</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#A6ACCD;">String</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">fromCharCode</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">0x61</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">99</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// &quot;ac&quot;</span></span>
<span class="line"></span></code></pre></div><ul><li>增补字符</li></ul><blockquote><p>对于 U+0000~U+FFFF 范围内的字符，length,charAt,charCodeAt,fromCharCode 返回的结果预期是一样的。因为在这个范围内，每个字符的都是用 16 位表示的。而这几个方法都是基于 16 位来操作的。</p></blockquote><blockquote><p>在 js 中增补字符是用两个 16 位字符来表示的</p></blockquote><blockquote><p>对于增补字符，即除开 65536 个字符，处理其它的字符时，上面的几个方法可能会出问题。</p></blockquote><p>如表情符号 😊,码元值是<code>0x1F60A === 128522</code></p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> m </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">ab😊cd</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">m</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">length </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">6</span></span>
<span class="line"><span style="color:#A6ACCD;">m</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">charAt</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">2</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// &quot;\ud83d&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">m</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">charAt</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">3</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// &quot;\ude0a&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">m</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">charAt</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">4</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// c</span></span>
<span class="line"></span></code></pre></div><ul><li>codePointAt 方法</li></ul><p>代替 charCodeAt 方法，返回索引位置的码点，码点可能是 16 位，也可能是 32 位</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> m </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">ab😊cd</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">m</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">codePointAt</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">1</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// 98</span></span>
<span class="line"><span style="color:#A6ACCD;">m</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">codePointAt</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">2</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// 128522</span></span>
<span class="line"><span style="color:#A6ACCD;">m</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">codePointAt</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">3</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// 56482</span></span>
<span class="line"></span></code></pre></div><ul><li>fromCodePoint 方法</li></ul><p>代替 fromCharCode,接收任意数量的码点，返回对应字符拼接起来的字符串</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#A6ACCD;">String</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">fromCharCode</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">98</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">55357</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">56842</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">98</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// &quot;b😊b&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">String</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">fromCodePoint</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">98</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">128522</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">98</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// &quot;b😊b&quot;</span></span>
<span class="line"></span></code></pre></div><ul><li><strong>字符串操作方法</strong></li></ul><p>三个从字符串汇总提取子字符串的方法</p><table><thead><tr><th>方法</th><th>说明</th><th>示例</th></tr></thead><tbody><tr><td>slice</td><td>接收两个参数，第一个是开始位置，第二个是结束位置</td><td><code>&#39;abcd&#39;.slice(0,2)</code> 输出<code>ab</code></td></tr><tr><td>substr</td><td>接收两个参数，第一个是开始位置，第二个是提取子字符串数量</td><td><code>&#39;abcd&#39;.substr(2,1)</code>输出 <code>c</code></td></tr><tr><td>substring</td><td>接收两个参数，第一个是开始位置，第二个是结束位置</td><td><code>&#39;abcd&#39;.substring(0,2)</code> 输出<code>ab</code></td></tr></tbody></table><p>这三个方法第二个参数不传，会默认到结束位置</p><ul><li><strong>字符串位置方法</strong></li></ul><p><code>indexOf</code>和<code>lastIndexOf</code>方法，从字符串中搜索传入的字符串，并返回位置，没找到返回-1</p><p>lastIndexOf 是从末尾开始查找</p><p>它们也支持传入第二个参数，表示开始搜索的位置</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">abcd</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">indexOf</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">b</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// 1</span></span>
<span class="line"></span></code></pre></div><ul><li><strong>字符串包含方法</strong></li></ul><p><code>startsWith,endsWith,includes</code>方法，都从字符串中搜索传入的字符串，返回一个布尔值</p><p>区别在于 startsWith 从 0 开始搜索，endsWith 从结尾开始搜索</p><p>startsWith 和 includes 接收第二个参数，表示开始搜索的位置</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> m </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">abcd</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">m</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">startsWith</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">b</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// false</span></span>
<span class="line"><span style="color:#A6ACCD;">m</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">startsWith</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">ab</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// true</span></span>
<span class="line"><span style="color:#A6ACCD;">m</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">includes</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">c</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// true</span></span>
<span class="line"></span></code></pre></div><ul><li>trim 方法</li></ul><p>创建一个副本，删除前后空格，并返回结果</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;"> a d </span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">trim</span><span style="color:#A6ACCD;">() </span><span style="color:#676E95;font-style:italic;">// &#39;a d&#39;</span></span>
<span class="line"></span></code></pre></div><ul><li>repeat 方法</li></ul><p>接收一个整数，表示要将字符串重复多少次</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">ab</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">repeat</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">3</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// &#39;ababab&#39;</span></span>
<span class="line"></span></code></pre></div><ul><li>padStart 和 padEnd 方法</li></ul><p>填为指定长度的字符串,默认填充空格，传入第二个参数则填充第二个参数</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">ab</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">padStart</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">4</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">.</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// &#39;ab..&#39;</span></span>
<span class="line"></span></code></pre></div><ul><li><strong>字符串迭代与解构</strong></li></ul><p>字符串的原型上有一个<code>@@iterator</code>方法，表示可以迭代字符串的每个字符。</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> m </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">abc</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> mIterator </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> m[Symbol</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">iterator]()</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(mIterator</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">next</span><span style="color:#A6ACCD;">()) </span><span style="color:#676E95;font-style:italic;">// {value:&#39;a&#39;,done:false}</span></span>
<span class="line"></span></code></pre></div><p>有了迭代器方法，可以使用<code>for-of</code>循环访问每个字符，也可以解构字符串。</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#89DDFF;font-style:italic;">for</span><span style="color:#A6ACCD;"> (</span><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> v </span><span style="color:#89DDFF;">of</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">abc</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">v</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// a</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// b</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// c</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> m </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">abc</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">([</span><span style="color:#89DDFF;">...</span><span style="color:#A6ACCD;">m]) </span><span style="color:#676E95;font-style:italic;">// [&quot;a&quot;,&quot;b&quot;,&quot;c&quot;]</span></span>
<span class="line"></span></code></pre></div><ul><li><strong>字符串大小写转换</strong></li></ul><p>提供<code>toLowerCase</code>和<code>toUpperCase</code>方法，以及特定地区的实现<code>toLocaleLowerCase</code> 和<code>toLocaleUpperCase</code></p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">mA</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">toLowerCase</span><span style="color:#A6ACCD;">() </span><span style="color:#676E95;font-style:italic;">// ma</span></span>
<span class="line"><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">mA</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">toUpperCase</span><span style="color:#A6ACCD;">() </span><span style="color:#676E95;font-style:italic;">// MA</span></span>
<span class="line"></span></code></pre></div><ul><li><strong>字符串模式匹配方法</strong></li><li>match 方法</li></ul><p>和 RegExp 的<code>exec</code>方法相同，match()方法返回的数组与 RegExp 对象的 exec()方法返回的数组是一样的：第一个元素是与整 个模式匹配的字符串，其余元素则是与表达式中的捕获组匹配的字符串（如果有的话）。</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> text </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">cat, bat, sat, fat</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> pattern </span><span style="color:#89DDFF;">=</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">/</span><span style="color:#C3E88D;">.at</span><span style="color:#89DDFF;">/</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 等价于 pattern.exec(text)</span></span>
<span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> matches </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> text</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">match</span><span style="color:#A6ACCD;">(pattern)</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(matches</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">index) </span><span style="color:#676E95;font-style:italic;">// 0</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(matches[</span><span style="color:#F78C6C;">0</span><span style="color:#A6ACCD;">]) </span><span style="color:#676E95;font-style:italic;">// &quot;cat&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(pattern</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">lastIndex) </span><span style="color:#676E95;font-style:italic;">// 0</span></span>
<span class="line"></span></code></pre></div><ul><li>search 方法</li></ul><p>这个方法返回模式第一个匹配的位置，未匹配返回-1</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> text </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">cat, bat, sat, fat</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> pos </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> text</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">search</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">/</span><span style="color:#C3E88D;">at</span><span style="color:#89DDFF;">/</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(pos) </span><span style="color:#676E95;font-style:italic;">// 1</span></span>
<span class="line"></span></code></pre></div><ul><li>replace 方法</li></ul><p>这个方法接收两个参数，第一个 参数可以是一个 RegExp 对象或一个字符串（这个字符串不会转换为正则表达式），第二个参数可以是 一个字符串或一个函数。如果第一个参数是字符串，那么只会替换第一个子字符串。要想替换所有子字 符串，第一个参数必须为正则表达式并且带全局标记</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> text </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">cat, bat, sat, fat</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> result </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> text</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">replace</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">at</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">ond</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(result) </span><span style="color:#676E95;font-style:italic;">// &quot;cond, bat, sat, fat&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">result </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> text</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">replace</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">/</span><span style="color:#C3E88D;">at</span><span style="color:#89DDFF;">/</span><span style="color:#F78C6C;">g</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">ond</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(result) </span><span style="color:#676E95;font-style:italic;">// &quot;cond, bond, sond, fond&quot;</span></span>
<span class="line"></span></code></pre></div><p>第二个参数是字符串的情况下，有几个特殊的字符序列，可以用来插入正则表达式操作的值</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> text </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">cat, bat, sat, fat</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">result </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> text</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">replace</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">/(</span><span style="color:#C3E88D;">.at</span><span style="color:#89DDFF;">)/</span><span style="color:#F78C6C;">g</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">word ($1)</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(result) </span><span style="color:#676E95;font-style:italic;">// word (cat), word (bat), word (sat), word (fat)</span></span>
<span class="line"></span></code></pre></div><p>第二个参数是函数是，会收到三个参数，与整 个模式匹配的字符串、匹配项在字符串中的开始位置，以及整个字符串。在有多个捕获组的情况下，每 个匹配捕获组的字符串也会作为参数传给这个函数，但最后两个参数还是与整个模式匹配的开始位置和 原始字符串。这个函数应该返回一个字符串</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">htmlEscape</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">text</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">text</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">replace</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">/[</span><span style="color:#C3E88D;">&lt;&gt;&quot;&amp;</span><span style="color:#89DDFF;">]/</span><span style="color:#F78C6C;">g</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">function</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">match</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;font-style:italic;">pos</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;font-style:italic;">originalText</span><span style="color:#89DDFF;">)</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">switch</span><span style="color:#F07178;"> (</span><span style="color:#A6ACCD;">match</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;font-style:italic;">case</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">&lt;</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">&amp;lt;</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;font-style:italic;">case</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">&gt;</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">&amp;gt;</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;font-style:italic;">case</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">&amp;</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">&amp;amp;</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;font-style:italic;">case</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">&quot;</span><span style="color:#89DDFF;">&#39;</span><span style="color:#89DDFF;">:</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">&amp;quot;</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(</span><span style="color:#82AAFF;">htmlEscape</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">&lt;p class=&quot;greeting&quot;&gt;Hello world!&lt;/p&gt;</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">))</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// &quot;&amp;lt;p class=&amp;quot;greeting&amp;quot;&amp;gt;Hello world!&lt;/p&gt;&quot;</span></span>
<span class="line"></span></code></pre></div><ul><li>split 方法</li></ul><p>根据传入的分隔符，将字符串拆分成数组,可接收第二个参数，表示返回数组的大小，不会超过这个</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> colorText </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">red,blue,green,yellow</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> colors1 </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> colorText</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">split</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// [&quot;red&quot;, &quot;blue&quot;, &quot;green&quot;, &quot;yellow&quot;]</span></span>
<span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> colors2 </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> colorText</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">split</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">2</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// [&quot;red&quot;, &quot;blue&quot;]</span></span>
<span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> colors3 </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> colorText</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">split</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">/[^</span><span style="color:#C3E88D;">,</span><span style="color:#89DDFF;">]+/</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// [&quot;&quot;, &quot;,&quot;, &quot;,&quot;, &quot;,&quot;, &quot;&quot;] 除了逗号，其它的都作为分隔符</span></span>
<span class="line"></span></code></pre></div><ul><li>localeCompare 方法</li></ul><p>按照字母表顺序比较两个字符串</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> stringValue </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">yellow</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(stringValue</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">localeCompare</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">brick</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">)) </span><span style="color:#676E95;font-style:italic;">// 1</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(stringValue</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">localeCompare</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">yellow</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">)) </span><span style="color:#676E95;font-style:italic;">// 0</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(stringValue</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">localeCompare</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">zoo</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">)) </span><span style="color:#676E95;font-style:italic;">// -1 yellow应该排在zoo前头，返回-1</span></span>
<span class="line"></span></code></pre></div><h3 id="_5-4-单例内置对象" tabindex="-1">5.4 单例内置对象 <a class="header-anchor" href="#_5-4-单例内置对象" aria-hidden="true">#</a></h3><h4 id="_5-4-1-global" tabindex="-1">5.4.1 Global <a class="header-anchor" href="#_5-4-1-global" aria-hidden="true">#</a></h4><ul><li><code>encodeURI()</code>和<code>encodeURIComponent()</code></li></ul><p>encodeURI 方法对整个 URI 进行编码，不会编码属于 URL 组件的特殊字符，比如<code>:</code>、<code>/</code>、<code>?</code>、<code>#</code>、<code>&amp;</code>号等。</p><p>而<code>encodeURIComponent</code>则会编码所有非标准字符，如下：</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> uri </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">https://www.nuobel.com/ele&gt;a.html</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#82AAFF;">encodeURI</span><span style="color:#A6ACCD;">(uri) </span><span style="color:#676E95;font-style:italic;">// &quot;https://www.nuobel.com/ele%3Ea.html&quot;</span></span>
<span class="line"><span style="color:#82AAFF;">encodeURIComponent</span><span style="color:#A6ACCD;">(uri) </span><span style="color:#676E95;font-style:italic;">//&quot;https%3A%2F%2Fwww.nuobel.com%2Fele%3Ea.html&quot;</span></span>
<span class="line"></span></code></pre></div><h4 id="_5-4-2-math" tabindex="-1">5.4.2 Math <a class="header-anchor" href="#_5-4-2-math" aria-hidden="true">#</a></h4><ul><li>**random()**方法</li></ul><p><code>random()</code>方法返回<code>[0,1)</code>的随机数，包括 0，不包括 1。</p><p>如下是一个从一组整整数中随机选择一个数的公式：</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> number </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> Math</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">floor</span><span style="color:#A6ACCD;">(Math</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">random</span><span style="color:#A6ACCD;">() </span><span style="color:#89DDFF;">*</span><span style="color:#A6ACCD;"> total_choices </span><span style="color:#89DDFF;">+</span><span style="color:#A6ACCD;"> first_value)</span></span>
<span class="line"></span></code></pre></div><p><code>total_choices</code>表示的可选总数，<code>first_value</code>表示最小可能的值。</p><p>比如你要在 2-10 中随机选择一个，包括 2 和 10，那么可选总数就是<code>10-2+1=9</code>，最小可能值为<code>2</code>。</p><p>写成一个方法更方便：</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">selectFrom</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">lowerValue</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">upperValue</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">let</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">totalChoices</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">upperValue</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">-</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">lowerValue</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">+</span><span style="color:#F07178;"> </span><span style="color:#F78C6C;">1</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">Math</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">floor</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">Math</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">random</span><span style="color:#F07178;">() </span><span style="color:#89DDFF;">*</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">totalChoices</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">+</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">lowerValue</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> num </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">selectFrom</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">2</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">10</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(num) </span><span style="color:#676E95;font-style:italic;">// 输出2-10的随机整数</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> a </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> [</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">red</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">blue</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">green</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">]</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(a[</span><span style="color:#82AAFF;">selectFrom</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">0</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">2</span><span style="color:#A6ACCD;">)]) </span><span style="color:#676E95;font-style:italic;">// 随机输出数组中的颜色</span></span>
<span class="line"></span></code></pre></div><h2 id="_6-集合引用类型" tabindex="-1">6.集合引用类型 <a class="header-anchor" href="#_6-集合引用类型" aria-hidden="true">#</a></h2><h3 id="_6-1-object" tabindex="-1">6.1 Object <a class="header-anchor" href="#_6-1-object" aria-hidden="true">#</a></h3><ul><li>对象的数值属性会自动转为字符串</li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#676E95;font-style:italic;">// 5会转换成字符串属性&quot;5&quot;</span></span>
<span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> person </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">5</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">fsdf</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span></code></pre></div><h3 id="_6-2array" tabindex="-1">6.2Array <a class="header-anchor" href="#_6-2array" aria-hidden="true">#</a></h3><h4 id="_1-创建数组" tabindex="-1">1.创建数组 <a class="header-anchor" href="#_1-创建数组" aria-hidden="true">#</a></h4><ul><li>构造函数和字面量形式创建</li><li><code>Array.from()</code>方法，把一个类数组转换成数组实例，可迭代的都能转</li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#676E95;font-style:italic;">// 可接收三个参数,第二个是个函数，每个项会调用它，第三个是第二个函数的this。但第二个函数是个箭头函数时this无用</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> a1 </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> [</span><span style="color:#F78C6C;">1</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">2</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">3</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">4</span><span style="color:#A6ACCD;">]</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> a2 </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> Array</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">from</span><span style="color:#A6ACCD;">(a1</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">x</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#A6ACCD;"> x </span><span style="color:#89DDFF;">**</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">2</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> a3 </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> Array</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">from</span><span style="color:#A6ACCD;">(</span></span>
<span class="line"><span style="color:#A6ACCD;">  a1</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">x</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">x</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">**</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">this.</span><span style="color:#A6ACCD;">exponent</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">},</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">{</span><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">exponent</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">2</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(a2) </span><span style="color:#676E95;font-style:italic;">// [1, 4, 9, 16]</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(a3) </span><span style="color:#676E95;font-style:italic;">// [1, 4, 9, 16]</span></span>
<span class="line"></span></code></pre></div><ul><li><code>Array.of()</code>方法，将一组参数转为数组实例</li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(Array</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">of</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">1</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">2</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">3</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">4</span><span style="color:#A6ACCD;">)) </span><span style="color:#676E95;font-style:italic;">// [1, 2, 3, 4]</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(Array</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">of</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">undefined</span><span style="color:#A6ACCD;">)) </span><span style="color:#676E95;font-style:italic;">// [undefined]</span></span>
<span class="line"></span></code></pre></div><h4 id="_2-检测数组" tabindex="-1">2.检测数组 <a class="header-anchor" href="#_2-检测数组" aria-hidden="true">#</a></h4><ul><li>在只有一个网页中，使用 instanceof 操作符即可判断</li><li>如果网页有多个框架，多个全局上下文，则应该使用<code>Array.isArray</code></li></ul><h4 id="_3-迭代器方法" tabindex="-1">3.迭代器方法 <a class="header-anchor" href="#_3-迭代器方法" aria-hidden="true">#</a></h4><p><code>keys,values,entries</code>三个方法，分别获取索引、值和索引值组合,返回值都是迭代器</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> a </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> [</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">foo</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">bar</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">baz</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">qux</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">]</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 因为这些方法都返回迭代器，所以可以将它们的内容</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 通过 Array.from()直接转换为数组实例</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> aKeys </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> Array</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">from</span><span style="color:#A6ACCD;">(a</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">keys</span><span style="color:#A6ACCD;">())</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> aValues </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> Array</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">from</span><span style="color:#A6ACCD;">(a</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">values</span><span style="color:#A6ACCD;">())</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> aEntries </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> Array</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">from</span><span style="color:#A6ACCD;">(a</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">entries</span><span style="color:#A6ACCD;">())</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(aKeys) </span><span style="color:#676E95;font-style:italic;">// [0, 1, 2, 3]</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(aValues) </span><span style="color:#676E95;font-style:italic;">// [&quot;foo&quot;, &quot;bar&quot;, &quot;baz&quot;, &quot;qux&quot;]</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(aEntries) </span><span style="color:#676E95;font-style:italic;">// [[0, &quot;foo&quot;], [1, &quot;bar&quot;], [2, &quot;baz&quot;], [3, &quot;qux&quot;]]</span></span>
<span class="line"></span></code></pre></div><h4 id="_4-复制和填充方法" tabindex="-1">4.复制和填充方法 <a class="header-anchor" href="#_4-复制和填充方法" aria-hidden="true">#</a></h4><ul><li>fill 方法</li></ul><div class="language-JS"><button title="Copy Code" class="copy"></button><span class="lang">JS</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> zeroes </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> [</span><span style="color:#F78C6C;">0</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0</span><span style="color:#A6ACCD;">]</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 用 5 填充整个数组</span></span>
<span class="line"><span style="color:#A6ACCD;">zeroes</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">fill</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">5</span><span style="color:#A6ACCD;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(zeroes)</span><span style="color:#89DDFF;">;</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">// [5, 5, 5, 5, 5]</span></span>
<span class="line"><span style="color:#A6ACCD;">zeroes</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">fill</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">0</span><span style="color:#A6ACCD;">)</span><span style="color:#89DDFF;">;</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">// 重置</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 用 6 填充索引大于等于 3 的元素</span></span>
<span class="line"><span style="color:#A6ACCD;">zeroes</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">fill</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">6</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">3</span><span style="color:#A6ACCD;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(zeroes)</span><span style="color:#89DDFF;">;</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">// [0, 0, 0, 6, 6]</span></span>
<span class="line"><span style="color:#A6ACCD;">zeroes</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">fill</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">0</span><span style="color:#A6ACCD;">)</span><span style="color:#89DDFF;">;</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">// 重置</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 用 7 填充索引大于等于 1 且小于 3 的元素</span></span>
<span class="line"><span style="color:#A6ACCD;">zeroes</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">fill</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">7</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">3</span><span style="color:#A6ACCD;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(zeroes)</span><span style="color:#89DDFF;">;</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">// [0, 7, 7, 0, 0];</span></span>
<span class="line"><span style="color:#A6ACCD;">zeroes</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">fill</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">0</span><span style="color:#A6ACCD;">)</span><span style="color:#89DDFF;">;</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">// 重置</span></span>
<span class="line"></span></code></pre></div><h4 id="_5-转换方法" tabindex="-1">5.转换方法 <a class="header-anchor" href="#_5-转换方法" aria-hidden="true">#</a></h4><ul><li>valueOf 方法返回数组本身</li><li>toString 方法返回由数组中每个值的等效字符串拼接而成的一个逗号分割的字符串</li><li>join 方法，接收一个分隔符，返回拼接后的字符串</li></ul><p>如果数组中某项是 null 或 undefined，则 toString 和 join 方法会以空字符串表示</p><h4 id="_6-排序方法" tabindex="-1">6.排序方法 <a class="header-anchor" href="#_6-排序方法" aria-hidden="true">#</a></h4><ul><li><code>sort()</code>方法</li></ul><p><code>sort</code>默认会按照升序方式排列数组元素。为此，sort 会在每一项上调用<code>String()</code>转型函数，然后比较字符串的顺序来进行排序。</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> values </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> [</span><span style="color:#F78C6C;">0</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">5</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">10</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">15</span><span style="color:#A6ACCD;">]</span></span>
<span class="line"><span style="color:#A6ACCD;">values</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">sort</span><span style="color:#A6ACCD;">() </span><span style="color:#676E95;font-style:italic;">// [0, 1, 10, 15, 5]</span></span>
<span class="line"></span></code></pre></div><p>可知明显不符合我们的数值排序期望。因此 sort 还可以接受一个<strong>比较函数</strong>，用于自定义判断排列顺序。</p><p>比较函数接收两个参数，如果第一个参数应该排在第二个参数前，返回负值；相等返回 0；如果第一个参数应该排在第二个参数后，返回正值。</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> values </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> [</span><span style="color:#F78C6C;">0</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">5</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">10</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">15</span><span style="color:#A6ACCD;">]</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 升序</span></span>
<span class="line"><span style="color:#A6ACCD;">values</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">sort</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">v1</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">v2</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">v1</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">-</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">v2</span></span>
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// [0, 1, 5, 10, 15]</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 降序</span></span>
<span class="line"><span style="color:#A6ACCD;">values</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">sort</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">v1</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">v2</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">v2</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">-</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">v1</span></span>
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">//  [15, 10, 5, 1, 0]</span></span>
<span class="line"></span></code></pre></div><h4 id="_7-操作方法" tabindex="-1">7. 操作方法 <a class="header-anchor" href="#_7-操作方法" aria-hidden="true">#</a></h4><ul><li><code>concat()</code>方法</li></ul><p><code>concat()</code>方法首先会创建一个当前数组的副本，然后再把它的参数添加到副本末尾，最后返回这个新构建的数组。</p><p>如果传入一个或多个数组，则会把这些数组的<strong>每一项</strong>添加到结果数组（打平）。如果参数不是数组，则直接把他们添加到数组末尾。</p><p>要不要打平数组，可以使用符号<code>Symbol.isConcatSpreadable</code>，数组默认值为<code>true</code>代表打平数组，置为 false 则阻止打平。</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> a1 </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> [</span><span style="color:#F78C6C;">1</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">2</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">3</span><span style="color:#A6ACCD;">]</span></span>
<span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> a2 </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> [</span><span style="color:#F78C6C;">4</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">5</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">6</span><span style="color:#A6ACCD;">]</span></span>
<span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> result1 </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> a1</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">concat</span><span style="color:#A6ACCD;">(a2) </span><span style="color:#676E95;font-style:italic;">// [1, 2, 3, 4, 5, 6]</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">a2[Symbol</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">isConcatSpreadable] </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#FF9CAC;">false</span></span>
<span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> result2 </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> a1</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">concat</span><span style="color:#A6ACCD;">(a2) </span><span style="color:#676E95;font-style:italic;">// [1, 2, 3, Array(3)]</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 打平类数组</span></span>
<span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> otherArray </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F78C6C;">0</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">a</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F78C6C;">1</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">b</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F07178;">length</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">2</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F07178;">[</span><span style="color:#A6ACCD;">Symbol</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">isConcatSpreadable</span><span style="color:#F07178;">]</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#FF9CAC;">true</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> result3 </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> a1</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">concat</span><span style="color:#A6ACCD;">(otherArray) </span><span style="color:#676E95;font-style:italic;">// [1, 2, 3, &quot;a&quot;, &quot;b&quot;]</span></span>
<span class="line"></span></code></pre></div><h3 id="_6-3-定型数组" tabindex="-1">6.3 定型数组 <a class="header-anchor" href="#_6-3-定型数组" aria-hidden="true">#</a></h3><h4 id="_1-历史" tabindex="-1">1. 历史 <a class="header-anchor" href="#_1-历史" aria-hidden="true">#</a></h4><p>WebGL 早期版本中，因为 JavaScript 数组与原生数组之间不匹配，所以出现了性能问题。图形驱动程序 API 通常不需要以 Javascript 默认双精度浮点格式传递给他们的数值，而这恰恰是 JavaScript 数组在内存中的格式。因此每次 WebGL 与 js 运行时之间传递数组时，都需要在数值转型中花费很多时间。这明显是不能接受的，所以才会有类型数组。</p><h4 id="_2-arraybuffer" tabindex="-1">2. ArrayBuffer <a class="header-anchor" href="#_2-arraybuffer" aria-hidden="true">#</a></h4><p><code>ArrayBuffer</code>是所有定型数组及视图引用的基本单位，可以允许 js 运行时访问一块名为<code>ArrayBuffer</code>的预分配内存。</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> buf </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">ArrayBuffer</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">16</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// 分配16个字节的内存</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(buf</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">byteLength) </span><span style="color:#676E95;font-style:italic;">// 16</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> buf2 </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> buf1</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">slice</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">4</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">12</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(buf2</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">byteLength) </span><span style="color:#676E95;font-style:italic;">// 8</span></span>
<span class="line"></span></code></pre></div><p>要读取或写入<code>ArrayBuffer</code>，就必须通过视图。视图有不同的类型，但引用的都是 ArrayBuffer 中存储的二进制数据。</p><p>能使用<code>ArrayBuffer</code>的有视图<code>DataView</code>和定型数组（<code>Int32Array</code>、<code>Int16Array</code>等）</p><h3 id="_6-4-map" tabindex="-1">6.4 Map <a class="header-anchor" href="#_6-4-map" aria-hidden="true">#</a></h3><h4 id="_1-map-的方法" tabindex="-1">1.map 的方法 <a class="header-anchor" href="#_1-map-的方法" aria-hidden="true">#</a></h4><ul><li>有<code>size,set(key,value),get(key),has(key),delete(key),clear()</code>等属性和方法</li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> m </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">Map</span><span style="color:#A6ACCD;">([</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">key1</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">val1</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">])</span></span>
<span class="line"></span></code></pre></div><ul><li><code>mapIns.keys(),mapIns.entries(),mapIns.values()</code>返回对应的迭代器（使用 next 或者 for...of）进行迭代</li></ul><h4 id="_2-选-object-还是-map" tabindex="-1">2.选 Object 还是 Map <a class="header-anchor" href="#_2-选-object-还是-map" aria-hidden="true">#</a></h4><ul><li>对于多数 web 开发来说，选谁没有多大区别</li><li>对于在乎内存和性能的开发者来说，是有差别的： <ul><li>给定固定的内存大小，Map 可以比 Object 多存储 50%的键值对</li><li>插入性能，如果代码涉及大量插入操作，Map 会好点</li><li>如果代码涉及大量查找操作，选 Object 可能会好点</li><li>如果代码涉及大量删除操作，选 Map 会好点</li></ul></li></ul><h3 id="_6-6-set" tabindex="-1">6.6 Set <a class="header-anchor" href="#_6-6-set" aria-hidden="true">#</a></h3><h4 id="_1-set-的方法" tabindex="-1">1.Set 的方法 <a class="header-anchor" href="#_1-set-的方法" aria-hidden="true">#</a></h4><ul><li><code>has(val),add(val),size,delete(val)</code>等属性和方法</li><li>常用<code>setIns.values()</code>方法返回迭代器，对值进行迭代</li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> s </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">Set</span><span style="color:#A6ACCD;">()</span></span>
<span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> s1 </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">Set</span><span style="color:#A6ACCD;">([</span><span style="color:#F78C6C;">1</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">2</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">3</span><span style="color:#A6ACCD;">])</span></span>
<span class="line"></span></code></pre></div><h3 id="_6-8-迭代与扩展操作" tabindex="-1">6.8 迭代与扩展操作 <a class="header-anchor" href="#_6-8-迭代与扩展操作" aria-hidden="true">#</a></h3><p>es6 新增的迭代器和扩展操作符，对集合引用类型特别有用。这些新特性让集合类型之间的相互操作、复制和修改变得异常方便。</p><p>有 4 种原生集合类型定义了默认迭代器：</p><ul><li>Array</li><li>所有定型数组</li><li>Map</li><li>Set</li></ul><p>意味着所有上述类型都支持顺序迭代，可以传入 for...of 中:</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> iterableThings </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> [</span></span>
<span class="line"><span style="color:#A6ACCD;">  Array</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">of</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">1</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">2</span><span style="color:#A6ACCD;">)</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">  (typedArr </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> Int16Array</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">of</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">3</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">4</span><span style="color:#A6ACCD;">))</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">Map</span><span style="color:#A6ACCD;">([</span></span>
<span class="line"><span style="color:#A6ACCD;">    [</span><span style="color:#F78C6C;">5</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">6</span><span style="color:#A6ACCD;">]</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">    [</span><span style="color:#F78C6C;">7</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">8</span><span style="color:#A6ACCD;">]</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">  ])</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">Set</span><span style="color:#A6ACCD;">([</span><span style="color:#F78C6C;">9</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">10</span><span style="color:#A6ACCD;">])</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">]</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">for</span><span style="color:#A6ACCD;"> (</span><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> iterableThing </span><span style="color:#89DDFF;">of</span><span style="color:#A6ACCD;"> iterableThings) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">for</span><span style="color:#F07178;"> (</span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">x</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">of</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">iterableThing</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">x</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 1</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 2</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 3</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 4</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// [5, 6]</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// [7, 8]</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 9</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 10</span></span>
<span class="line"></span></code></pre></div><h2 id="_7-迭代器与生成器" tabindex="-1">7.迭代器与生成器 <a class="header-anchor" href="#_7-迭代器与生成器" aria-hidden="true">#</a></h2><p>无</p><h2 id="_8-对象、类与面向对象编程" tabindex="-1">8.对象、类与面向对象编程 <a class="header-anchor" href="#_8-对象、类与面向对象编程" aria-hidden="true">#</a></h2><h3 id="_8-1-理解对象" tabindex="-1">8.1 理解对象 <a class="header-anchor" href="#_8-1-理解对象" aria-hidden="true">#</a></h3><h4 id="_8-1-7-对象解构" tabindex="-1">8.1.7 对象解构 <a class="header-anchor" href="#_8-1-7-对象解构" aria-hidden="true">#</a></h4><ul><li><strong>解构</strong> 解构在内部使用<code>ToObject()</code>把源数据结构转换为对象。这意味着，原始值会被转换为对象。同时<code>null</code>和<code>undefined</code>不能被解构，否则会抛出错误。</li></ul><p>如下：</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#A6ACCD;"> length </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">abc</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(length) </span><span style="color:#676E95;font-style:italic;">// 3   字符串在解构中被转换为String对象</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">constructor</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> c </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">4</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(c </span><span style="color:#89DDFF;">===</span><span style="color:#A6ACCD;"> Number) </span><span style="color:#676E95;font-style:italic;">// true  数字在解构中被转换为Number对象</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#A6ACCD;"> _ </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">null</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">// TypeError</span></span>
<span class="line"></span></code></pre></div><h3 id="_8-2-创建对象" tabindex="-1">8.2 创建对象 <a class="header-anchor" href="#_8-2-创建对象" aria-hidden="true">#</a></h3><h4 id="_8-2-4-原型模式" tabindex="-1">8.2.4 原型模式 <a class="header-anchor" href="#_8-2-4-原型模式" aria-hidden="true">#</a></h4><ul><li><p><strong>01.理解原型</strong></p><p>实例与构造函数的原型之间有直接的联系，但实例与构造函数没有。</p><p>构造函数、原型对象和实例，是三个完全不同的对象。</p><p>实例通过<code>__proto__</code>链接到原型对象，它实际上就是隐藏特性<code>[[Proptotype]]</code>。</p><p>构造函数通过<code>prototype</code>属性链接到原型对象。</p><p>实例通过<code>__proto__.constructor</code>间接指向构造函数，实际上就是原型对象<code>prototype.constructor</code>指向了构造函数。</p></li></ul><h3 id="_8-4-类" tabindex="-1">8.4 类 <a class="header-anchor" href="#_8-4-类" aria-hidden="true">#</a></h3><h4 id="_8-4-2-类构造函数" tabindex="-1">8.4.2 类构造函数 <a class="header-anchor" href="#_8-4-2-类构造函数" aria-hidden="true">#</a></h4><p>类构造函数与构造函数的主要区别是，调用类构造函数必须使用<code>new</code>操作符。而普通构造函数如果不使用<code>new</code>操作符，那么就会以全局的<code>this</code>(通常是 window)作为内部对象。</p><h2 id="_9-代理与反射" tabindex="-1">9.代理与反射 <a class="header-anchor" href="#_9-代理与反射" aria-hidden="true">#</a></h2><h3 id="_9-1-代理基础" tabindex="-1">9.1 代理基础 <a class="header-anchor" href="#_9-1-代理基础" aria-hidden="true">#</a></h3><h3 id="_9-3-代理模式" tabindex="-1">9.3 代理模式 <a class="header-anchor" href="#_9-3-代理模式" aria-hidden="true">#</a></h3><p>使用代理可以在代码中实现一些有用的编程模式，代理的应用场景是不可限量的。如下。</p><h4 id="_9-3-1-跟踪属性访问" tabindex="-1">9.3.1 跟踪属性访问 <a class="header-anchor" href="#_9-3-1-跟踪属性访问" aria-hidden="true">#</a></h4><p>通过捕获<code>get</code>、<code>set</code>和<code>has</code>等操作，可以知道对象属性何时在何处被访问和查询过：</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> user </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F07178;">name</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">huyu</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> proxy </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">Proxy</span><span style="color:#A6ACCD;">(user</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F07178;">get</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">t</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">property</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">receiver</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">`</span><span style="color:#C3E88D;">访问</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">property</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">属性</span><span style="color:#89DDFF;">`</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">Reflect</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">get</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">...</span><span style="color:#A6ACCD;">arguments</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">},</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F07178;">set</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">t</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">property</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">value</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">receiver</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">`</span><span style="color:#C3E88D;">设置属性</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">property</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">值为</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">value</span><span style="color:#89DDFF;">}`</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">Reflect</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">set</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">...</span><span style="color:#A6ACCD;">arguments</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">},</span></span>
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(proxy</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">name) </span><span style="color:#676E95;font-style:italic;">// 访问name属性   // huyu</span></span>
<span class="line"><span style="color:#A6ACCD;">proxy</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">name </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">huyu2</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">// 设置属性name值为huyu2</span></span>
<span class="line"></span></code></pre></div><h4 id="_9-3-2-隐藏属性" tabindex="-1">9.3.2 隐藏属性 <a class="header-anchor" href="#_9-3-2-隐藏属性" aria-hidden="true">#</a></h4><p>代理的这些特性，让我们要隐藏目标对象上的属性也很容易，比如：</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> hideProperty </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> [</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">name</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">]</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> user </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F07178;">name</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">huyu</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F07178;">age</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">27</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> proxy </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">Proxy</span><span style="color:#A6ACCD;">(user</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F07178;">get</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">t</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">property</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">receiver</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;"> (</span><span style="color:#A6ACCD;">hideProperty</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">includes</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">property</span><span style="color:#F07178;">)) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">undefined</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">Reflect</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">get</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">...</span><span style="color:#A6ACCD;">arguments</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">},</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F07178;">has</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">t</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">property</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;"> (</span><span style="color:#A6ACCD;">hideProperty</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">includes</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">property</span><span style="color:#F07178;">)) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#FF9CAC;">false</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">Reflect</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">has</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">...</span><span style="color:#A6ACCD;">arguments</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">},</span></span>
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(proxy</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">name) </span><span style="color:#676E95;font-style:italic;">// undefined</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(proxy</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">age) </span><span style="color:#676E95;font-style:italic;">//27</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">name</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">in</span><span style="color:#A6ACCD;"> proxy) </span><span style="color:#676E95;font-style:italic;">// false</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">age</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">in</span><span style="color:#A6ACCD;"> proxy) </span><span style="color:#676E95;font-style:italic;">// true</span></span>
<span class="line"></span></code></pre></div><h4 id="_9-3-3-属性验证" tabindex="-1">9.3.3 属性验证 <a class="header-anchor" href="#_9-3-3-属性验证" aria-hidden="true">#</a></h4><p>所有的赋值操作都会触发<code>set()</code>捕获器，所有可以根据所赋的值决定是允许还是拒绝赋值.</p><h4 id="_9-3-4-函数与构造函数参数验证" tabindex="-1">9.3.4 函数与构造函数参数验证 <a class="header-anchor" href="#_9-3-4-函数与构造函数参数验证" aria-hidden="true">#</a></h4><p>和验证对象属性类似，也可以使用<code>apply</code>和<code>construct</code>捕获器来对函数和构造函数的参数进行审查，如下：</p><ul><li>函数参数验证</li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">numAdd</span><span style="color:#89DDFF;">(...</span><span style="color:#A6ACCD;font-style:italic;">nums</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">nums</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">reduce</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">pre</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;font-style:italic;">cur</span><span style="color:#89DDFF;">)</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">pre</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">+</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">cur</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> proxyNumAdd </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">Proxy</span><span style="color:#A6ACCD;">(numAdd</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">  </span><span style="color:#676E95;font-style:italic;">// 这里，高程四电子书是...argsList，</span></span>
<span class="line"><span style="color:#89DDFF;">  </span><span style="color:#676E95;font-style:italic;">//但根据定义应该是所有参数列表都在argsList里，它本身就是个类数组对象，不用再使用...操作符收集</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F07178;">apply</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">target</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">thisArg</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">argsList</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">for</span><span style="color:#F07178;"> (</span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">n</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">of</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">argsList</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;"> (</span><span style="color:#89DDFF;">typeof</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">n</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">!==</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">number</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#89DDFF;font-style:italic;">throw</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">参数必须都是数字</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">Reflect</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">apply</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">...</span><span style="color:#A6ACCD;">arguments</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">},</span></span>
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(</span><span style="color:#82AAFF;">proxyNumAdd</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">1</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">2</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">3</span><span style="color:#A6ACCD;">)) </span><span style="color:#676E95;font-style:italic;">// 6</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(</span><span style="color:#82AAFF;">proxyNumAdd</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">1</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">2</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">3</span><span style="color:#A6ACCD;">)) </span><span style="color:#676E95;font-style:italic;">// Uncaught 参数必须都是数字</span></span>
<span class="line"></span></code></pre></div><ul><li>类构造函数参数验证</li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">User</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#C792EA;">constructor</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">id</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">this.</span><span style="color:#A6ACCD;">id</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">id</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">`</span><span style="color:#C3E88D;">id=</span><span style="color:#89DDFF;">${</span><span style="color:#89DDFF;">this.</span><span style="color:#A6ACCD;">id</span><span style="color:#89DDFF;">}`</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> ProxyNumAdd </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">Proxy</span><span style="color:#A6ACCD;">(User</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F07178;">construct</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">target</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">argsList</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">newTarget</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;"> (</span><span style="color:#89DDFF;">typeof</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">argsList</span><span style="color:#F07178;">[</span><span style="color:#F78C6C;">0</span><span style="color:#F07178;">] </span><span style="color:#89DDFF;">===</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">undefined</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;font-style:italic;">throw</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">构造函数必须传入id</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">Reflect</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">construct</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">...</span><span style="color:#A6ACCD;">arguments</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">},</span></span>
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">ProxyNumAdd</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">1</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// id=1</span></span>
<span class="line"><span style="color:#89DDFF;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">ProxyNumAdd</span><span style="color:#A6ACCD;">() </span><span style="color:#676E95;font-style:italic;">// Uncaught 构造函数必须传入id</span></span>
<span class="line"></span></code></pre></div><h4 id="_9-3-5-数据绑定与可观察对象" tabindex="-1">9.3.5 数据绑定与可观察对象 <a class="header-anchor" href="#_9-3-5-数据绑定与可观察对象" aria-hidden="true">#</a></h4><p>通过代理，可以做一些中间操作，比如可以将类的实例都放进一个集合里面，或者在属性更改时发送消息：</p><ul><li>实例收集</li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> userList </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> []</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">User</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#C792EA;">constructor</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">id</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">this.</span><span style="color:#A6ACCD;">id</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">id</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> handler </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F07178;">construct</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">target</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">argsList</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">newTarget</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#C792EA;">let</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">userIns</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">Reflect</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">construct</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">...</span><span style="color:#A6ACCD;">arguments</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">userList</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">push</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">userIns</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">userIns</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">},</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> ProxyUser </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">Proxy</span><span style="color:#A6ACCD;">(User</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> handler)</span></span>
<span class="line"><span style="color:#89DDFF;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">ProxyUser</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">1</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#89DDFF;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">ProxyUser</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">2</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#89DDFF;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">ProxyUser</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">3</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">for</span><span style="color:#A6ACCD;"> (</span><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> u </span><span style="color:#89DDFF;">of</span><span style="color:#A6ACCD;"> userList) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">u</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">id</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 1</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 2</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 3</span></span>
<span class="line"></span></code></pre></div><ul><li>数据更新发送消息</li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> nums </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> []</span></span>
<span class="line"><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">emit</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">msg</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">msg</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> proxyNums </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">Proxy</span><span style="color:#A6ACCD;">(nums</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F07178;">set</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">target</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">property</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">value</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#82AAFF;">emit</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">`</span><span style="color:#C3E88D;">设置属性</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">property</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">的值为</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">value</span><span style="color:#89DDFF;">}`</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">Reflect</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">set</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">...</span><span style="color:#A6ACCD;">arguments</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">},</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F07178;">deleteProperty</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">target</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">property</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#82AAFF;">emit</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">`</span><span style="color:#C3E88D;">删除属性</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">property</span><span style="color:#89DDFF;">}`</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">Reflect</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">deleteProperty</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">...</span><span style="color:#A6ACCD;">arguments</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">},</span></span>
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">proxyNums</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">push</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">a</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">proxyNums</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">push</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">b</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">proxyNums</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">pop</span><span style="color:#A6ACCD;">()</span></span>
<span class="line"><span style="color:#89DDFF;">delete</span><span style="color:#A6ACCD;"> proxyNums[</span><span style="color:#F78C6C;">0</span><span style="color:#A6ACCD;">]</span></span>
<span class="line"><span style="color:#A6ACCD;">proxyNums[</span><span style="color:#F78C6C;">0</span><span style="color:#A6ACCD;">] </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">c</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(proxyNums)</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(nums </span><span style="color:#89DDFF;">===</span><span style="color:#A6ACCD;"> proxyNums)</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 输出</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">/*</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">设置属性0的值为a</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">设置属性length的值为1</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">设置属性1的值为b</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">设置属性length的值为2</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">删除属性1</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">设置属性length的值为1</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">删除属性0</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">设置属性0的值为c</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">Proxy {0: &quot;c&quot;}[[Handler]]: Object[[Target]]: Array(1)[[IsRevoked]]: false</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">false</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">*/</span></span>
<span class="line"></span></code></pre></div><h2 id="_10-函数" tabindex="-1">10.函数 <a class="header-anchor" href="#_10-函数" aria-hidden="true">#</a></h2><h3 id="_10-1-箭头函数" tabindex="-1">10.1 箭头函数 <a class="header-anchor" href="#_10-1-箭头函数" aria-hidden="true">#</a></h3><p>箭头函数不能使用<code>arguments</code>、<code>super</code>和<code>new.target</code>，也不能用作构造函数。 另外，箭头函数也没有<code>prototype</code>属性。</p><h3 id="_10-9-函数内部" tabindex="-1">10.9 函数内部 <a class="header-anchor" href="#_10-9-函数内部" aria-hidden="true">#</a></h3><h4 id="_1-this" tabindex="-1">1.this <a class="header-anchor" href="#_1-this" aria-hidden="true">#</a></h4><p>在箭头函数中，<code>this</code>引用的是定义箭头函数的上下文。</p><h2 id="_11-期约与异步函数" tabindex="-1">11.期约与异步函数 <a class="header-anchor" href="#_11-期约与异步函数" aria-hidden="true">#</a></h2><h3 id="_11-2-期约" tabindex="-1">11.2 期约 <a class="header-anchor" href="#_11-2-期约" aria-hidden="true">#</a></h3><h4 id="_1-promises-a-规范" tabindex="-1">1.Promises/A+规范 <a class="header-anchor" href="#_1-promises-a-规范" aria-hidden="true">#</a></h4><p>早期的期约机制在 jQuery 和 Dojo 中是以 Deferred API 的形式出现的</p><p>2010 年，CommonJS 项目实现的 Promises/A 规范日益流行，Q 和 Bluebird 等第三方期约库也越来越被认可</p><p>2012 年，Promises/A+组织 fork 了 CommonJS 的 Promises/A 建议，制定了 Promises/A+规范</p><h4 id="_2-期约基础" tabindex="-1">2.期约基础 <a class="header-anchor" href="#_2-期约基础" aria-hidden="true">#</a></h4><ul><li>期约是一个有状态的对象，它能处于一下 3 种状态之一： <ul><li>待定（pending）</li><li>兑现（fulfilled），也成为解决（resolved）</li><li>拒绝（rejected）</li></ul></li><li>待定是期约的初始状态，可以落定（settled）为兑现和拒绝，不论落定为哪种状态，都是<strong>不可逆的</strong></li><li><code>Promise.resolve()</code>是一个幂等方法 <ul><li>如果传入的参数本身是一个期约，那它的行为就是一个空包装</li></ul></li><li><code>Promise.reject()</code>没有幂等逻辑，如果给他传一个期约，则这个期约会成为它返回拒绝期约的<strong>理由</strong></li></ul><h4 id="_3-期约的实例方法" tabindex="-1">3.期约的实例方法 <a class="header-anchor" href="#_3-期约的实例方法" aria-hidden="true">#</a></h4><ul><li>期约的实例方法是连接外部同步代码与内部异步代码之间的桥梁 <ul><li>Promise.prototype.then()</li><li>Promise.prototype.catch()</li><li>Promise.prototype.finally()</li></ul></li><li>每个期约实例的方法（then、catch 和 finally）都会返回一个<strong>新的期约对象</strong></li><li>thenable 接口，实现了<code>then()</code>方法的对象即实现了 thenable 接口</li><li>拒绝期约与拒绝错误处理</li></ul><p>异步错误只能通过异步的<code>onRejected</code>处理程序捕获：</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#676E95;font-style:italic;">// 正确</span></span>
<span class="line"><span style="color:#FFCB6B;">Promise</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">reject</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">reject1</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">)</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">catch</span><span style="color:#A6ACCD;">(</span><span style="color:#A6ACCD;font-style:italic;">e</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">error</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">e</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 错误，捕获不到</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">try</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#FFCB6B;">Promise</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">reject</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">reject1</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">catch</span><span style="color:#A6ACCD;"> (error) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">error</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">error</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span></code></pre></div><ul><li>拒绝处理程序在捕获错误后，应该返回<strong>一个解决期约</strong></li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#FFCB6B;">Promise</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">reject</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">22</span><span style="color:#A6ACCD;">)</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">catch</span><span style="color:#A6ACCD;">(</span><span style="color:#A6ACCD;font-style:italic;">e</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">bar</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// Promise &lt;fulfilled&gt;:bar</span></span>
<span class="line"></span></code></pre></div><ul><li><p>finally 方法</p><ul><li>该处理程序没有办法知道期约的状态是解决还是拒绝</li><li>多数情况它会原样后传父期约</li><li>如果返回的内部返回的是一个待定的或者抛出错误的拒绝期约，则 finally 返回响应的期约</li></ul></li><li><p>如果给期约添加了多个处理程序，当期约状态变化时，相关处理程序会按照<strong>添加它们的顺序一次执行</strong></p></li></ul><h3 id="_11-3-异步函数" tabindex="-1">11.3 异步函数 <a class="header-anchor" href="#_11-3-异步函数" aria-hidden="true">#</a></h3><h4 id="_1-async" tabindex="-1">1.async <a class="header-anchor" href="#_1-async" aria-hidden="true">#</a></h4><ul><li>用于声明异步函数，并返回一个期约对象</li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">async</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">one</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#F78C6C;">1</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#82AAFF;">one</span><span style="color:#A6ACCD;">()</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">then</span><span style="color:#A6ACCD;">(console</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">log) </span><span style="color:#676E95;font-style:italic;">// undefined</span></span>
<span class="line"></span></code></pre></div><ul><li>该函数的返回值会用<code>Promise.resolve()</code>进行包装</li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">async</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">two</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#F78C6C;">33</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#82AAFF;">two</span><span style="color:#A6ACCD;">()</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">then</span><span style="color:#A6ACCD;">(console</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">log) </span><span style="color:#676E95;font-style:italic;">// 33</span></span>
<span class="line"></span></code></pre></div><ul><li>返回值期待一个实现 thenable 接口的对象</li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">async</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">three</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">thenable</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    then</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">callback</span><span style="color:#89DDFF;">)</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#82AAFF;">callback</span><span style="color:#F07178;">(</span><span style="color:#F78C6C;">44</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">},</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">thenable</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#82AAFF;">three</span><span style="color:#A6ACCD;">()</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">then</span><span style="color:#A6ACCD;">(console</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">log) </span><span style="color:#676E95;font-style:italic;">// 44</span></span>
<span class="line"></span></code></pre></div><ul><li>如果在异步函数内部返回拒绝期约或抛出错误，则会返回拒绝期约</li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">async</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">four1</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#FFCB6B;">Promise</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">reject</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">error1</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#82AAFF;">four1</span><span style="color:#A6ACCD;">()</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">catch</span><span style="color:#A6ACCD;">(console</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">log) </span><span style="color:#676E95;font-style:italic;">// error1</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 不过拒绝期约的错误不会被异步函数捕获，需使用return返回才可以返回拒绝的期约</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 区别于下面的使用await</span></span>
<span class="line"><span style="color:#C792EA;">async</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">four12</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#FFCB6B;">Promise</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">reject</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">error12</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#82AAFF;">four12</span><span style="color:#A6ACCD;">()</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">catch</span><span style="color:#A6ACCD;">(console</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">log)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 以error对象实例作为拒绝理由</span></span>
<span class="line"><span style="color:#C792EA;">async</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">four2</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">throw</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">Error</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">error2</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#82AAFF;">four2</span><span style="color:#A6ACCD;">()</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">catch</span><span style="color:#A6ACCD;">(console</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">log) </span><span style="color:#676E95;font-style:italic;">// Error:error2</span></span>
<span class="line"></span></code></pre></div><h4 id="_2-await" tabindex="-1">2.await <a class="header-anchor" href="#_2-await" aria-hidden="true">#</a></h4><ul><li>使用 await 关键字可以暂停异步函数代码的执行(行为与 yield 类似)，等待期约解决</li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">async</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">one</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">let</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">p</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">new</span><span style="color:#F07178;"> </span><span style="color:#FFCB6B;">Promise</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">resolve</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;font-style:italic;">reject</span><span style="color:#89DDFF;">)</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">setTimeout</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">resolve</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#F78C6C;">1000</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#F78C6C;">111</span><span style="color:#F07178;">))</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;font-style:italic;">await</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">p</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#82AAFF;">one</span><span style="color:#A6ACCD;">() </span><span style="color:#676E95;font-style:italic;">// 111</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C792EA;">async</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">two</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">await</span><span style="color:#F07178;"> </span><span style="color:#FFCB6B;">Promise</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">resolve</span><span style="color:#F07178;">(</span><span style="color:#F78C6C;">222</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#82AAFF;">two</span><span style="color:#A6ACCD;">()</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">then</span><span style="color:#A6ACCD;">(console</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">log) </span><span style="color:#676E95;font-style:italic;">// 222</span></span>
<span class="line"></span></code></pre></div><ul><li>await 期待一个实现 thenable 的对象，如果不是则被当作一个被解决的期约</li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">async</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">two</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;font-style:italic;">await</span><span style="color:#F07178;"> </span><span style="color:#F78C6C;">2222</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#82AAFF;">two</span><span style="color:#A6ACCD;">() </span><span style="color:#676E95;font-style:italic;">// 222</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C792EA;">async</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">two2</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">thenable</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    then</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">cb</span><span style="color:#89DDFF;">)</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#82AAFF;">cb</span><span style="color:#F07178;">(</span><span style="color:#F78C6C;">333</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">},</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;font-style:italic;">await</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">thenable</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#82AAFF;">two2</span><span style="color:#A6ACCD;">() </span><span style="color:#676E95;font-style:italic;">// 333</span></span>
<span class="line"></span></code></pre></div><ul><li>等待错误或拒绝期约，会返回拒绝期约</li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">async</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">three</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#F78C6C;">1</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">await</span><span style="color:#F07178;"> (</span><span style="color:#89DDFF;">()</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">throw</span><span style="color:#F07178;"> </span><span style="color:#F78C6C;">333</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;">)()</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#F78C6C;">3</span><span style="color:#F07178;">) </span><span style="color:#676E95;font-style:italic;">// 不会执行</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#82AAFF;">three</span><span style="color:#A6ACCD;">()</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">catch</span><span style="color:#A6ACCD;">(console</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">log)</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">2</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 1</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 2</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 333</span></span>
<span class="line"></span></code></pre></div><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#676E95;font-style:italic;">// 对拒绝期约使用await会返回拒绝期约</span></span>
<span class="line"><span style="color:#C792EA;">async</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">three</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#F78C6C;">1</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">await</span><span style="color:#F07178;"> </span><span style="color:#FFCB6B;">Promise</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">reject</span><span style="color:#F07178;">(</span><span style="color:#F78C6C;">444</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#F78C6C;">3</span><span style="color:#F07178;">) </span><span style="color:#676E95;font-style:italic;">// 不会执行</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#82AAFF;">three</span><span style="color:#A6ACCD;">()</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">catch</span><span style="color:#A6ACCD;">(console</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">log)</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">2</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 1</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 2</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 444</span></span>
<span class="line"></span></code></pre></div><ul><li>await 关键字必须在异步函数中使用</li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">foo</span><span style="color:#89DDFF;">(){</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">await</span><span style="color:#F07178;"> </span><span style="color:#FFCB6B;">Promise</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">resolve</span><span style="color:#F07178;">(</span><span style="color:#F78C6C;">2</span><span style="color:#F07178;">) </span><span style="color:#676E95;font-style:italic;">// 不允许，出现在了同步函数中</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span></code></pre></div><h4 id="_3-停止和恢复执行" tabindex="-1">3.停止和恢复执行 <a class="header-anchor" href="#_3-停止和恢复执行" aria-hidden="true">#</a></h4><ul><li>js 运行时遇到 await 关键字，会记录在哪里暂停执行，等到 await 右边的值可用了，js 运行时会向<strong>消息队列推送一个任务</strong>，这个任务会恢复异步函数的执行。所以，await 下一行（即其余部分）会被<strong>异步求值</strong>，即使是一个立即可用的值</li></ul><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">async</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">foor</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#F78C6C;">2</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">await</span><span style="color:#F07178;"> </span><span style="color:#F78C6C;">1</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#F78C6C;">4</span><span style="color:#F07178;">) </span><span style="color:#676E95;font-style:italic;">// 被异步了</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">1</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#82AAFF;">foor</span><span style="color:#A6ACCD;">()</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">3</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 1</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 2</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 3</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 4</span></span>
<span class="line"></span></code></pre></div><h2 id="_12-bom" tabindex="-1">12 BOM <a class="header-anchor" href="#_12-bom" aria-hidden="true">#</a></h2><h3 id="_12-1-window-对象" tabindex="-1">12.1 window 对象 <a class="header-anchor" href="#_12-1-window-对象" aria-hidden="true">#</a></h3><h4 id="_12-1-3-窗口位置与像素比" tabindex="-1">12.1.3 窗口位置与像素比 <a class="header-anchor" href="#_12-1-3-窗口位置与像素比" aria-hidden="true">#</a></h4><ul><li>窗口位置</li></ul><p><code>screenLeft</code>和<code>screenTop</code>属性，用于表示窗口相对于屏幕左侧和顶部的位置，返回值的单位是 css 像素。</p><ul><li>像素比</li></ul><p>手机屏幕的物理分辨率可能是 1920x1080，但因为其像素可能非常小，所以浏览器就需要将其分辨率降为较低的<strong>逻辑</strong>分辨率，比如 640x320。 这个物理像素与 css 像素之间的转换比率由<code>window.devicePixelRatio</code>属性提供。</p><p>对于从 1920x1080 转换为 640x320 的设备，<code>window.devicePixelRatio</code>值就是 3.</p><h4 id="_12-1-4-窗口大小" tabindex="-1">12.1.4 窗口大小 <a class="header-anchor" href="#_12-1-4-窗口大小" aria-hidden="true">#</a></h4><p><code>window.innerWidth</code>和<code>window.innerHeight</code>返回视口的大小，也就是屏幕上页面可视区域的大小。</p><p>下面详细看下<code>window.innerWidth</code>、<code>document.documentElement.clientWidth</code>和<code>document.body.clientWidth</code>的示例：</p><p>页面的 html 如下：</p><div class="language-html"><button title="Copy Code" class="copy"></button><span class="lang">html</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#89DDFF;">&lt;!</span><span style="color:#F07178;">DOCTYPE</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">html</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">html</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">lang</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">en</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">head</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">meta</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">charset</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">UTF-8</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;"> /&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">meta</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">name</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">viewport</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">content</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">width=device-width, initial-scale=1.0</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;"> /&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">title</span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;">Document</span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">title</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#89DDFF;">    &lt;</span><span style="color:#F07178;">style</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#FFCB6B;">body</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#B2CCD6;">border</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1px</span><span style="color:#A6ACCD;"> solid red</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#B2CCD6;">height</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1200px</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">style</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">head</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;">body</span><span style="color:#89DDFF;">&gt;&lt;/</span><span style="color:#F07178;">body</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"><span style="color:#89DDFF;">&lt;/</span><span style="color:#F07178;">html</span><span style="color:#89DDFF;">&gt;</span></span>
<span class="line"></span></code></pre></div><p>显示页面如下：</p><p><img src="/assets/1.66e1d795.png" alt="图"></p><p>上图可以看出：</p><ul><li><p><code>window.innerWidth</code>是可视区域的大小，包括滚动条，值为 590</p></li><li><p><code>document.documentElement.clientWidth</code>是 html 元素的宽度，不包括滚动条，值为 573</p></li><li><p><code>document.body.clientWidth</code>是 body 的宽度，body 默认有一个 8px 的外边距，这里值为 555</p></li><li><p>同时，<code>document.body.clientHeight</code>值为 1200，<code>window.innerHeight</code>和<code>document.documentElement.clientHeight</code>的值相等，即可视区域的高度，这里都为 961.</p></li></ul><h4 id="_12-1-5-视口位置" tabindex="-1">12.1.5 视口位置 <a class="header-anchor" href="#_12-1-5-视口位置" aria-hidden="true">#</a></h4><p><code>window.pageXoffset/window.scrollX</code>和<code>window.pageYoffset/window.scrollY</code>都返回整个文档相对于视口滚动的距离。</p><p>可以使用<code>scroll()</code>、<code>scrollTo()</code>和<code>scrollBy()</code>方法滚动页面。</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#676E95;font-style:italic;">// 滚动到距离顶部100像素的地方</span></span>
<span class="line"><span style="color:#A6ACCD;">window</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">scrollTo</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">0</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">100</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 相对于当前视口向下滚动10像素</span></span>
<span class="line"><span style="color:#A6ACCD;">window</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">scrollBy</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">0</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">10</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 平滑滚动</span></span>
<span class="line"><span style="color:#A6ACCD;">window</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">scrollTo</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F07178;">left</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F07178;">top</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">100</span><span style="color:#89DDFF;">,</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#F07178;">behavior</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">smooth</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">// 默认是auto</span></span>
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"></span></code></pre></div><h3 id="_12-2-location-对象" tabindex="-1">12.2 location 对象 <a class="header-anchor" href="#_12-2-location-对象" aria-hidden="true">#</a></h3><h4 id="操作地址" tabindex="-1">操作地址 <a class="header-anchor" href="#操作地址" aria-hidden="true">#</a></h4><p>除了<code>hash</code>外，只要修改<code>location</code>的一个属性，就会导致页面重新加载新 URL。</p><ul><li>location.reload</li></ul><p><code>reload()</code>方法能重新加载当前显示的页面。它默认会以最有效的方式重新加载。可能从缓存中加载页面，如果想强制从服务器重新加载，可以给 reload 方法传个<code>true</code>。</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#A6ACCD;">location</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">reload</span><span style="color:#A6ACCD;">() </span><span style="color:#676E95;font-style:italic;">// 重新加载，可能从缓存加载</span></span>
<span class="line"><span style="color:#A6ACCD;">location</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">reload</span><span style="color:#A6ACCD;">(</span><span style="color:#FF9CAC;">true</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// 重新加载，从服务器加载</span></span>
<span class="line"></span></code></pre></div><h3 id="_12-3-navigator-对象" tabindex="-1">12.3 navigator 对象 <a class="header-anchor" href="#_12-3-navigator-对象" aria-hidden="true">#</a></h3><p>最早是 Netscape Navigator2 引入，现在已经成为客户端标识浏览器的标准，通常用于确定浏览器的类型。</p><p>下面列一下比较有用的属性和方法：</p><table><thead><tr><th>属性/方法</th><th>说明</th></tr></thead><tbody><tr><td>cookieEnabled</td><td>布尔值，表示是否启用了 cookie</td></tr><tr><td>deviceMemory</td><td>返回单位为 GB 的设备内存容量</td></tr><tr><td>gelocation</td><td>返回暴露 Geolocation API 的<code>Geolocation</code>对象</td></tr><tr><td>hardwareConcurrency</td><td>返回设备的处理球核心数量，逻辑处理器的个数</td></tr><tr><td>platform</td><td>返回浏览器运行的系统平台</td></tr><tr><td>userAgent</td><td>返回浏览器的用户代理字符串</td></tr></tbody></table><h3 id="_12-4-screen-对象" tabindex="-1">12.4 screen 对象 <a class="header-anchor" href="#_12-4-screen-对象" aria-hidden="true">#</a></h3><p>较少用，一般查看客户端显示器的像素高宽，如：</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#A6ACCD;">screen</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">width </span><span style="color:#676E95;font-style:italic;">// 1920</span></span>
<span class="line"><span style="color:#A6ACCD;">screen</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">height </span><span style="color:#676E95;font-style:italic;">// 1080</span></span>
<span class="line"><span style="color:#A6ACCD;">screen</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">availHeight </span><span style="color:#676E95;font-style:italic;">// 1050 去除底部window菜单的可用高度，如果有。</span></span>
<span class="line"></span></code></pre></div><h3 id="_12-5-history-对象" tabindex="-1">12.5 history 对象 <a class="header-anchor" href="#_12-5-history-对象" aria-hidden="true">#</a></h3><p><code>history</code>是 window 的属性，所有每个<code>window</code>都有自己的 history 对象。</p><h4 id="_12-5-1-导航" tabindex="-1">12.5.1 导航 <a class="header-anchor" href="#_12-5-1-导航" aria-hidden="true">#</a></h4><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#676E95;font-style:italic;">// 后退一页</span></span>
<span class="line"><span style="color:#A6ACCD;">history</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">go</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">-</span><span style="color:#F78C6C;">1</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 前进一页</span></span>
<span class="line"><span style="color:#A6ACCD;">history</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">go</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">1</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 前进两页</span></span>
<span class="line"><span style="color:#A6ACCD;">history</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">go</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">2</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 导航到最近的nuobel.com页面</span></span>
<span class="line"><span style="color:#A6ACCD;">history</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">go</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">nuobel.com</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 后退一页</span></span>
<span class="line"><span style="color:#A6ACCD;">history</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">back</span><span style="color:#A6ACCD;">()</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 前进一页</span></span>
<span class="line"><span style="color:#A6ACCD;">history</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">forward</span><span style="color:#A6ACCD;">()</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#A6ACCD;"> (history</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">length </span><span style="color:#89DDFF;">===</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1</span><span style="color:#A6ACCD;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">  </span><span style="color:#676E95;font-style:italic;">// 这是用户窗口中的第一个页面</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span></code></pre></div><h4 id="_12-5-2-历史状态管理" tabindex="-1">12.5.2 历史状态管理 <a class="header-anchor" href="#_12-5-2-历史状态管理" aria-hidden="true">#</a></h4><ul><li><code>pushState()</code>方法</li></ul><p>接收三个参数：一个 state 对象（最大 1MB）、一个新的状态标题（目前没啥用）和一个可选的相对 URL。</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> stateObject </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">foo</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">bar</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">history</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">pushState</span><span style="color:#A6ACCD;">(stateObject</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">My title</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">baz.html</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"></span></code></pre></div><p><code>pushState()</code>执行先后，状态信息会被推到历史记录中，浏览器地址栏也会改变为新的相对 URL。</p><p>除了这些外，浏览器不会向服务器发送请求。</p><ul><li><code>popstate</code>事件</li></ul><p>点击后退时触发。</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#A6ACCD;">window</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">addEventListener</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">popstate</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">event</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">let</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">state</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">event</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">state</span></span>
<span class="line"><span style="color:#89DDFF;">  </span><span style="color:#676E95;font-style:italic;">// pushState传入的第一个参数</span></span>
<span class="line"><span style="color:#89DDFF;">  </span><span style="color:#676E95;font-style:italic;">// 第一个页面加载时状态是null</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;"> (</span><span style="color:#A6ACCD;">state</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#82AAFF;">processState</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">state</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"></span></code></pre></div><p>后退后，应该把页面重置为状态对象所对应的页面状态（浏览器不会自动为你做这些）。</p><blockquote><p><strong>注意</strong>，使用 HTML5 状态管理时，要确保通过<code>pushState()</code>创建的&quot;假&quot;URL 背后都对应着服务器上的真实物理 URL。否则，刷新时会导致 404。所有单页应用（SPA）框架都必须通过服务器货客户端的某些配置解决此问题。</p></blockquote><h2 id="_13-客户端检测" tabindex="-1">13.客户端检测 <a class="header-anchor" href="#_13-客户端检测" aria-hidden="true">#</a></h2><h3 id="_13-3-软件与硬件检测" tabindex="-1">13.3 软件与硬件检测 <a class="header-anchor" href="#_13-3-软件与硬件检测" aria-hidden="true">#</a></h3><h4 id="_13-3-2-浏览器元数据" tabindex="-1">13.3.2 浏览器元数据 <a class="header-anchor" href="#_13-3-2-浏览器元数据" aria-hidden="true">#</a></h4><ul><li>Geolocation API</li></ul><p><code>navigator.geolocation</code>属性暴露了 Geolocation API，可以让浏览器脚本感知当前设备的地理位置。这个 API 只在安全执行环境（通过<strong>HTTPS</strong>获取的脚本）中可用。</p><p>获取浏览器当前的位置，可以使用<code>getCurrentPosition()</code>方法，语法如下：</p><blockquote><p>navigator.geolocation.getCurrentPosition(success, error, options)</p></blockquote><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#A6ACCD;">navigator</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">geolocation</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getCurrentPosition</span><span style="color:#A6ACCD;">(</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#A6ACCD;font-style:italic;">position</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">position</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">timestamp</span><span style="color:#F07178;">) </span><span style="color:#676E95;font-style:italic;">// 查询时间戳 1600828839408</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">position</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">coords</span><span style="color:#F07178;">) </span><span style="color:#676E95;font-style:italic;">//  GeolocationCoordinates对象，如下</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#676E95;font-style:italic;">/*</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">    coords: {</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">      accuracy: 241  // 以米为单位的精度</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">      altitude: null  // 海拔高度</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">      altitudeAccuracy: null  // 海拔高度的精度，以米为单位</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">      heading: null // 朝向，表示相对于正北方向移动的角度（0&lt;=heading&lt;360）</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">      latitude: 30.233179  // 纬度</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">      longitude: 120.192787 // 经度</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">      speed: null // 设备每秒移动的速度</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">    }</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">    */</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">},</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#A6ACCD;font-style:italic;">e</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 回调失败</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// e.code是一个整数，有三个值</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// PERMISSION_DENIED(1):浏览器未被允许访问设备位置</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// POSITION_UNAVAILABLE(2):系统无法返回任何位置信息。</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// TIMEOUT(3):系统在超时时间内无法返回位置信息。</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 另外e.message会提供更完整的错误信息</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">)</span></span>
<span class="line"></span></code></pre></div><p>第三个参数通过<code>PositionOptions</code>对象来配置。如下：</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#FFCB6B;">enableHightAccuracy</span><span style="color:#89DDFF;">:</span><span style="color:#FF9CAC;">false</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#676E95;font-style:italic;">// true表示尽量精确，默认false，以最快最省电的方式返回。</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#FFCB6B;">timeout</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;">毫秒</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#676E95;font-style:italic;">// 表示超时时间，默认值0xffffffff</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#FFCB6B;">maximumAge</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;">毫秒</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#676E95;font-style:italic;">// 表示返回坐标的最长有效期。在有效期内会使用缓存返回之前存储的坐标。</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span></code></pre></div><h4 id="_13-3-3-硬件" tabindex="-1">13.3.3 硬件 <a class="header-anchor" href="#_13-3-3-硬件" aria-hidden="true">#</a></h4><ul><li>处理器核心</li></ul><p><code>navigator.hardwareConcurrency</code>属性返回浏览器可以并行执行的最大工作线程，不一定是实际 CPU 的核心数。</p><ul><li>设备内存大小</li></ul><p><code>navigator.deviceMemory</code>属性返回设备大致的系统内存大小，以 GB 为单位。不太准确，我的笔记本 16GB，返回的是 8。</p></div></div></main><!--[--><!--]--><footer class="VPDocFooter" data-v-c5936a1e data-v-e033cd21><div class="edit-info" data-v-e033cd21><!----><div class="last-updated" data-v-e033cd21><p class="VPLastUpdated" data-v-e033cd21 data-v-355aa5ef>更新时间: <time datetime="2023-03-01T15:45:52.000Z" data-v-355aa5ef></time></p></div></div><div class="prev-next" data-v-e033cd21><div class="pager" data-v-e033cd21><!----></div><div class="pager" data-v-e033cd21><a class="pager-link next" href="/blog/readingNotes/jsgc4-2.html" data-v-e033cd21><span class="desc" data-v-e033cd21>下一篇</span><span class="title" data-v-e033cd21>第14-26章</span></a></div></div></footer><!--[--><!--]--></div></div></div></div></div><!----><!--[--><!--]--></div></div>
    <script>__VP_HASH_MAP__ = JSON.parse("{\"about_me.md\":\"a6963ed5\",\"about_contact.md\":\"753dd087\",\"blog_interviews_project-for-frontend-interview-questions-collection.md\":\"3ac3f621\",\"blog_svg_jiaohu.md\":\"bdc89024\",\"index.md\":\"ac84e241\",\"blog_svg_lujing.md\":\"2247252e\",\"blog_svg_lvjing.md\":\"7fb98f9e\",\"blog_svg_rumen.md\":\"760fcfc8\",\"blog_svg_tuanhejianbian.md\":\"1d67f731\",\"blog_svg_userspaceonuse-and-objectboundingbox.md\":\"7135675e\",\"blog_svg_wendangjiegou.md\":\"659e2114\",\"english_how.md\":\"47ca54fc\",\"blog_svg_zuobiaoxitong.md\":\"9f073aa7\",\"blog_svg_zuobiaoxitongbianhuan.md\":\"09c91562\",\"english_howtolearnword.md\":\"29e67a9c\",\"english_plan.md\":\"d3863f0d\",\"english_string.md\":\"afd02e54\",\"blog_interviews_css-for-frontend-interview-questions-collection.md\":\"ad8ec08c\",\"blog_interviews_index.md\":\"7922302b\",\"blog_interviews_javascript-for-frontend-interview-questions-collection.md\":\"1f97ba08\",\"blog_interviews_mian-shi-xin-de.md\":\"f249f58c\",\"blog_interviews_pingtouge-interview-questions-collection.md\":\"01898e13\",\"life_car_baoxian.md\":\"1a0484fd\",\"life_index.md\":\"294ee10b\",\"life_car_jiaotongshiguchuli.md\":\"2dfb478a\",\"life_car_kaiche.md\":\"fb68bff5\",\"photograph_fujifilm_renxiangpeifang.md\":\"df9d71f0\",\"photograph_fujifilm_jiappianjichu.md\":\"e4797107\",\"blog_readingnotes_browserprinciple.md\":\"5600b029\",\"blog_interviews_webpack-for-frontend-interview-questions-collection.md\":\"5e087073\",\"photograph_fujifilm_fengguangpeifang.md\":\"1f3c5cc8\",\"blog_summary_20210702.md\":\"992c6ebc\",\"blog_summary_20210716.md\":\"27df70fd\",\"blog_summary_20210723.md\":\"b3df6f63\",\"blog_summary_20210730.md\":\"0fd6c31f\",\"blog_readingnotes_jsgc4-2.md\":\"754107dd\",\"blog_summary_20210806.md\":\"8ede013a\",\"blog_svg_caijianhemengban.md\":\"345a71fa\",\"blog_readingnotes_jsgc4.md\":\"badec6ec\",\"blog_2020_07_accumulation-fund-transform.md\":\"ea36b833\",\"blog_svg_jibenxingzhuang.md\":\"3d07ebc2\",\"photograph_home.md\":\"289914d9\",\"photograph_fujifilm_xiangjishezhi.md\":\"c859f451\",\"photograph_sheyingzhishi.md\":\"7db1fab8\",\"photograph_xiangjixuanze.md\":\"b38cb6f4\",\"wemedia_what.md\":\"1d28f58c\",\"wemedia_emoji.md\":\"234e5631\",\"blog_2020_07_css-modules-docs.md\":\"4575442d\",\"blog_2020_07_git-docs.md\":\"22c9808c\",\"blog_2020_07_http-cache-and-nginx-config.md\":\"82b01b17\",\"blog_svg_donghua.md\":\"87326708\",\"blog_2020_06_gatsby-markdown-blog-system.md\":\"87de2558\",\"blog_2020_06_ubuntu14.04-install-nginx-for-source-code.md\":\"eff6df3c\",\"blog_2020_07_throttle-and-debounce.md\":\"745f9ff3\",\"blog_2020_07_regex-in-javascript.md\":\"375103f6\",\"blog_finance_income.md\":\"90b9a5cf\",\"blog_interviews_safe-for-frontend-interview-questions-collection.md\":\"6ae808c2\",\"blog_2020_07_vim-docs.md\":\"50a62a76\",\"blog_2020_08_fiddler.md\":\"29bf9a9b\",\"blog_2020_11_webpack-how-to-load-chunks.md\":\"2fc96bb0\",\"blog_2020_07_use-react-framework-web-site.md\":\"f836a6bd\",\"blog_interviews_algorithm-javascript.md\":\"72bdd42b\",\"blog_summary_20210611.md\":\"4cc8a1ab\",\"blog_summary_20210529.md\":\"fb886442\",\"blog_interviews_babel-for-frontend-interview-questions-collection.md\":\"495cb8da\",\"blog_summary_20210124.md\":\"ee3946e0\",\"blog_summary_20210619.md\":\"ef11c68e\",\"blog_summary_20210626.md\":\"5d8d583c\",\"blog_svg_wenben.md\":\"4aaeb73b\",\"blog_interviews_html-for-frontend-interview-questions-collection.md\":\"78197e40\",\"blog_interviews_react-for-frontend-interview-questions-collection.md\":\"90e3af48\",\"blog_interviews_http-for-frontend-interview-questions-collection.md\":\"1129730d\",\"blog_frontend_library.md\":\"34c972ff\",\"blog_readingnotes_reactandnodejs.md\":\"8a99114b\"}")</script>
    <script type="module" async src="/assets/app.6facf8ba.js"></script>
    
  </body>
</html>